前不久项目中遇到一个问题:要求生成静态页面。
于是想到了velocity和FreeMarker。。。。
这是两个JAVA模板引擎,作为当前流行的几大MVC框架的有益补充,受到了开源框架Spring的支持。
下面总结一下初步FreeMarker应用。
1。要和Spring结合,首先要在Spring的Context中注册org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer的一个实例。
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/template/"/>
</bean>
2。编写模板:
比如,编写一个生成SQL脚本的模板。
<#if genreList?exists>
<#list genreList as commongenre>
INSERT INTO test1.tb_commongenre (vc2genrename) VALUES ('${commongenre?js_string}');
</#list>
</#if>
<#if cataList?exists>
<#list cataList as vc2catagorytagname>
INSERT INTO test1.tb_catagorytags (vc2catagorytagname) VALUES ('${vc2catagorytagname?js_string}');
</#list>
</#if>
<#if stdgenList?exists>
<#list stdgenList as vc2stdgenrename>
INSERT INTO test1.tb_stdgenre (vc2stdgenrename) VALUES ('${vc2stdgenrename?js_string}');
</#list>
</#if>
3:编写代码来生成最终的脚本。
public class MusicSqlGenerator {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
new String[] {"applicationContext.xml"});
private String tablename;
private String basePath = "/home/x-spirit";
public void genSql() throws Exception{
FreeMarkerConfigurer freemarkerConfig = (FreeMarkerConfigurer)ctx.getBean("freemarkerConfig");
Template tpl =freemarkerConfig.getConfiguration().getTemplate("newSQLTemplate.sql");
Map map = new HashMap();
map.put("stdgenList",readToList(new ArrayList<String>(), "tb_stdgenre",true,-1,-1));
String context = FreeMarkerTemplateUtils
.processTemplateIntoString(tpl, map);
PrintWriter pw = new PrintWriter(new FileOutputStream("c:/target.sql"));
pw.println(context);
pw.flush();
pw.close();
}
public String[] readToList(List<String> list,String tablename,boolean all,int start,int limit)throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(basePath+File.separator+tablename), "UTF-8"));
String s = null;
int i = 0;
int j = 0;
while((s=br.readLine())!=null){
if(all){
list.add(s);
}else{
if(++i>=start){
if(++j<=limit){
list.add(s);
}
}
}
}
String[] arr = list.toArray(new String[list.size()]);
return arr;
}
public static void main(String args[]){
try {
new MusicSqlGenerator().genSql();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
结果,当tb_stdgenre文件中包含将近100MB的数据时,程序出现堆内存泄露。。。因为这100MB的数据要在一个String对象里面存储实在是太多了。。。
于是研究了Spring的源代码和FreeMarker的源代码,对程序做了如下改进:
首先继承Spring里面的FreeMarkerTemplateUtils。这个类里面是把StringWriter传进去,最后返回一个String。。。这就是罪魁祸首阿。。那我直接把用于磁盘I/O的PrintWriter传进去好了,这样至少不会瞬间在内存里堆积大量的数据。
public class FreeMarkerTemplateUtils extends org.springframework.ui.freemarker.FreeMarkerTemplateUtils{
public static void processTemplateIntoFile(Template template, Object model,String filepath)
throws IOException, TemplateException {
PrintWriter pw = new PrintWriter(new FileOutputStream(filepath));
template.process(model, pw);
}
}
注意这段代码后面不需要对pw对象做flush()和close()。因为FreeMarker里面已经做过了。不相信的读者请自己去看源码。
接下来对原来的程序进行改造:
public class MusicSqlGenerator {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
new String[] {"applicationContext.xml"});
private String tablename;
private String basePath = "/home/x-spirit";
public void genSql() throws Exception{
FreeMarkerConfigurer freemarkerConfig = (FreeMarkerConfigurer)ctx.getBean("freemarkerConfig");
Template tpl =freemarkerConfig.getConfiguration().getTemplate("newSQLTemplate.sql");
Map map = new HashMap();
map.put("stdgenList",readToList(new ArrayList<String>(), "tb_stdgenre",true,-1,-1));
FreeMarkerTemplateUtils
.processTemplateIntoFile(tpl, map,"/home/x-spirit/results/musicStyle.sql");
}
public String[] readToList(List<String> list,String tablename,boolean all,int start,int limit)throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(basePath+File.separator+tablename), "UTF-8"));
String s = null;
int i = 0;
int j = 0;
while((s=br.readLine())!=null){
if(all){
list.add(s);
}else{
if(++i>=start){
if(++j<=limit){
list.add(s);
}
}
}
}
String[] arr = list.toArray(new String[list.size()]);
return arr;
}
public static void main(String args[]){
try {
new MusicSqlGenerator().genSql();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
好了。先写到这里。。。
总之,感觉Spring对FreeMarker的支持其实还不是特别的好,就是简单封装了一下。不过至少也为我们使用提供了参照范例。感谢Juergen Hoeller的启发。
分享到:
相关推荐
这篇“Freemarker学习笔记一【乱码解决】”将指导我们如何解决这个问题。 首先,我们需要了解乱码的常见原因。在Java Web开发中,乱码通常与以下因素有关: 1. **文件编码**:Freemarker模板文件(.ftl)的编码...
下面将详细解释FreeMarker的一些关键语法和特性,以及在实际应用中的使用。 ### 1. 对象输出 在FreeMarker中,可以直接输出对象的值。例如,如果在数据模型中有一个名为`name`的对象,可以使用`${name}`将其值插入...
这个“freemarker笔记”很可能是一个关于理解和使用FreeMarker模板语言的学习资料,其中可能涵盖了FreeMarker的基本概念、语法、以及在实际开发中的应用。 FreeMarker的核心概念是模板和数据模型。模板是HTML或者...
### Freemarker自学笔记 #### 一、Configuration 类详解 `Configuration` 类是 Freemarker 的核心类之一,负责管理 Freemarker 应用程序的各种配置参数。它不仅提供了对模板的加载和缓存支持,还允许开发者自定义...
Freemarker是一个强大的开源模板引擎,常用于Java应用程序中生成动态HTML、XML或其他文本格式的输出。它将数据模型与视图分离,使得开发者可以专注于业务逻辑,而设计师则可以专注于页面布局。以下是对Freemarker从...
描述:孔浩的Freemarker视频笔记,值得一看! 根据给定的文件信息,我们可以深入探讨Freemarker的相关知识点,包括其基本概念、工作流程以及具体的代码实现。 ### Freemarker基本概念 Freemarker是一个用Java语言...
1. **Freemarker中文手册.pdf**: 这份手册通常会详细介绍Freemarker的基本概念,如模板语言、模板数据模型以及模板的执行流程。其中,可能会讲解模板元素,如`<#if>`、`<#foreach>`等控制结构,以及`${expression}...
FreeMarker是一款强大...总的来说,FreeMarker是一款强大、灵活的模板引擎,它提供了丰富的功能和良好的可扩展性,适用于各种文本生成场景,尤其是在构建Web应用的视图层时,能够有效地提升开发效率和代码的可维护性。
**FreeMarker** 是一个模板引擎,主要用于生成动态HTML或其他文本格式的输出,广泛应用于Web应用中。在JEECMS中,FreeMarker被用作视图层的模板技术,允许开发者通过简单的模板语言与后台数据进行交互,生成动态网页...
通过阅读`freemarker语法.docx`和`freemarker笔记1.txt`,你可以更深入地了解这些规则,并结合实际项目进一步掌握Freemarker的使用。同时,参考提供的博客链接(https://kingpingping.iteye.com/blog/1144477),...
通过阅读这些笔记,你可以快速掌握Freemarker在实际项目中的应用技巧,避免一些常见的陷阱。 PDF文档《FreeMarker_Programmer Guide》通常会提供更深入的技术细节,包括模板语言的设计理念,以及如何与其他系统(如...
1. **Freemarker基础** - **模板语言**:Freemarker使用简单的文本模板语言,将数据模型与HTML或者其他格式的文档结合,动态生成输出。 - **变量表达式**:`${}`用来输出变量,`#{}`用于注释,`<#if>`、`<#else>`...
下面,我们将深入探讨FreeMarker的基础知识、应用场景以及如何进行学习。 1. **基础概念** - **模板**:FreeMarker的核心是模板,它是由开发者编写的HTML或XML文件,其中嵌入了特定的FreeMarker语法,用于动态生成...
1. **Freemaker_入门+深入+开发指南+学习笔记.doc**:这份文档通常包含了Freemarker的基础概念、快速入门教程、进阶技巧以及开发实践指导。通过阅读,我们可以了解到如何创建模板、变量的使用、控制结构(如if/else...
1. **Spring框架**:Spring是核心,它提供了一个全面的编程和配置模型,用于简化企业级Java应用开发。其特性包括依赖注入(DI)、面向切面编程(AOP)、事务管理以及大量的可插入的数据访问抽象,如JDBC、Hibernate...