FreeMarker 应用笔记(1)

前不久项目中遇到一个问题:要求生成静态页面。

于是想到了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的启发。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值