FreeMarker模板引擎基础应用
FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java编写,
模板用servlet提供的数据动态地生成HTML,模板语言是强大的直观的,编译器速度快,
输出接近静态HTML页面的速度。
一.Freemarker模板应用事例。
1.创建模板文件,在/resource/template目录下建立freemarkerLocal.ftl文件。
Java代码
------------------普通变量获取-------------------
${user}
---------获取Map中属性--------------
${latestProduct.url}
${latestProduct.name}
-------自定义的indexOf方法变量-------
<#assignx="something">
${indexOf("met",x)}
${indexOf("foo",x)}
------自定义的转换器变量(转换小写为大写,以标签形式展现)----------------
blah1
<@upperCase>
blah2
blah3
</@upperCase>
blah4
---------------共享变量的获取,在Configuration中设置---------------
<@to_upper>
${company}
</@to_upper>
2.代码解析模板文件输出。
Java代码
publicclassFreemarkerLocalTest{
publicstaticvoidmain(String[]args)throwsException{
/*一般在应用的整个生命周期中你仅需要执行一下代码一次*/
/*创建一个合适的configuration*/
Configurationcfg=newConfiguration();
//设置模板加载的方式
cfg.setDirectoryForTemplateLoading(
newFile("D:/myspace/freemarker/resource/template"));
//方式二(从Web上下文获取)
//voidsetServletContextForTemplateLoading(ObjectservletContext,Stringpath);
//设置模板共享变量,所有的模板都可以访问设置的共享变量
cfg.setSharedVariable("to_upper",newUpperCaseTransform());
cfg.setSharedVariable("company","FooInc.");
//指定模板如何查看数据模型
cfg.setObjectWrapper(newDefaultObjectWrapper());
//如果从多个位置加载模板,可采用以下方式
/**
FileTemplateLoaderftl1=newFileTemplateLoader(newFile("/tmp/templates"));
FileTemplateLoaderftl2=newFileTemplateLoader(newFile("/usr/data/templates"));
ClassTemplateLoaderctl=newClassTemplateLoader(getClass(),"");
TemplateLoader[]loaders=newTemplateLoader[]{ftl1,ftl2,ctl};
MultiTemplateLoadermtl=newMultiTemplateLoader(loaders);
cfg.setTemplateLoader(mtl);**/
/*而以下代码你通常会在一个应用生命周期中执行多次*/
/*获取或创建一个模版*/
Templatetemp=cfg.getTemplate("freemarkerLocal.ftl");
/*创建一个数据模型Createadatamodel*/
Maproot=newHashMap();
root.put("user","BigJoe");
Maplatest=newHashMap();
root.put("latestProduct",latest);
latest.put("url","products/greenmouse.html");
latest.put("name","greenmouse");
//方法变量,indexOf为自己定义的方法变量
root.put("indexOf",newIndexOfMethod());
//转换器变量
root.put("upperCase",newUpperCaseTransform());
/*合并数据模型和模版*/
Writerout=newOutputStreamWriter(System.out);
temp.process(root,out);
out.flush();
}
}
3.自定义的方法变量类IndexOfMethod
Java代码
publicclassIndexOfMethodimplementsTemplateMethodModel{
publicObjectexec(Listargs)throwsTemplateModelException{
if(args.size()!=2){
thrownewTemplateModelException("Wrongarguments");
}
//返回第一个字符串首次出现在第二个字符串的位置
returnnewSimpleNumber(((String)args.get(1))
.indexOf((String)args.get(0)));
}
}
4.自定义的转换器变量类UpperCaseTransform
Java代码
/**
*转换器变量,自定义自己的转换器标签
*/
importfreemarker.template.TemplateTransformModel;
publicclassUpperCaseTransformimplementsTemplateTransformModel{
//转换器接口方法,将会转换标签之间的内容,首先把标签之间的内容读取到Writer对象中,
//再由Writer对象对其中的内容施行转换处理,转换后的内容会再次存储到Writer中
publicWritergetWriter(Writerout,Mapargs){
returnnewUpperCaseWriter(out);
}
privateclassUpperCaseWriterextendsWriter{
privateWriterout;
UpperCaseWriter(Writerout){
this.out=out;
}
publicvoidwrite(char[]cbuf,intoff,intlen)throwsIOException{
out.write(newString(cbuf,off,len).toUpperCase());
}
publicvoidflush()throwsIOException{
out.flush();
}
//不用调用out.close,到达结束标签close会自动被调用
publicvoidclose(){
}
}
}
二.自动生成代码应用
1.创建模板文件,在/resource/template目录下建立codeModel.ftl文件。
Java代码
packagecom.order.model;
publicclass${class}{
<#listpropertiesasprop>
private${prop.type}${prop.name};
</#list>
<#listpropertiesasprop>
public${prop.type}get${prop.name?cap_first}(){
return${prop.name};
}
publicvoidset${prop.name?cap_first}(${prop.type}${prop.name}){
this.${prop.name}=${prop.name};
}
</#list>
}
2.应用代码生成模板文件。
Java代码
publicclassGenerateCodeTest{
publicstaticvoidmain(Stringargs[])throwsIOException,
TemplateException{
Configurationcfg=newConfiguration();
cfg.setDirectoryForTemplateLoading(newFile(
"D:/myspace/freemarker/resource/template/"));
cfg.setObjectWrapper(newDefaultObjectWrapper());
/*获取模板文件*/
Templatetemplate=cfg.getTemplate("codeModel.ftl");
/*模板数据*/
Map<String,Object>root=newHashMap<String,Object>();
root.put("class","Order");
Collection<Map<String,String>>properties=newHashSet<Map<String,String>>();
root.put("properties",properties);
/*字段1orderId*/
Map<String,String>orderId=newHashMap<String,String>();
orderId.put("name","orderId");
orderId.put("type","Long");
properties.add(orderId);
/*字段2orderName*/
Map<String,String>orderName=newHashMap<String,String>();
orderName.put("name","orderName");
orderName.put("type","String");
properties.add(orderName);
/*字段3money*/
Map<String,String>money=newHashMap<String,String>();
money.put("name","money");
money.put("type","Double");
properties.add(money);
/*生成输出到控制台*/
Writerout=newOutputStreamWriter(System.out);
template.process(root,out);
out.flush();
/*生成输出到文件*/
FilefileDir=newFile("D:/generateCodeFile");
//创建文件夹,不存在则创建
org.apache.commons.io.FileUtils.forceMkdir(fileDir);
//指定生成输出的文件
Fileoutput=newFile(fileDir+"/Order.java");
Writerwriter=newFileWriter(output);
template.process(root,writer);
writer.close();
}
}
三.JSP调用模板文件输出。
1.首先创建模板文件,在WEB-INF/templates目录下建立test.ftl文件。
Java代码
Hello,${name}!
2.解析模板文件类,传入pageContext参数。
Java代码
publicclassFreemarkerTest{
publicvoidexecute(PageContextpageContext)throwsException
{
Configurationcfg=newConfiguration();
//设置模板的路径
cfg.setServletContextForTemplateLoading(pageContext.getServletContext(),
"WEB-INF/templates");
Maproot=newHashMap();
root.put("name","Tom");
//获取模板文件
Templatet=cfg.getTemplate("test.ftl");
Writerout=pageContext.getResponse().getWriter();
t.process(root,out);
}
}
3.创建JSP文件调用输出。
Html代码
<%@pagelanguage="java"contentType="text/html;charset=GB2312"
pageEncoding="GB2312"%>
<%@pageimport="com.freemarker.test.FreemarkerTest;"%>
<!DOCTYPEhtmlPUBLIC"-//W3C//DTDHTML4.01Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<metahttp-equiv="Content-Type"content="text/html;charset=GB2312">
<title>HelloWorld</title>
</head>
<body>
<%
FreemarkerTestc1=newFreemarkerTest();
c1.execute(pageContext);
%>
</body>
</html>
四.Servlet调用模板文件生成html文件进行页面展示。
1.创建模板文件,在WebRoot/index目录下建立test.ftl文件。
Java代码
<html>
<body>
用户名:${userName}<br>
邮 箱:${email}
</body>
</html>
2.创建Servlet文件解析模板文件并生成html文件进行页面输出。
Java代码
publicclassFreemarkerServletTestextendsHttpServlet{
publicFreemarkerServletTest(){
super();
}
publicvoiddestroy(){
super.destroy();
}
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
doPost(request,response);
}
publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
//生成html后的文件
Stringpath=getServletContext().getRealPath("/")+"index.htm";
System.out.println(path);
try{
freemarker(request,"test.ftl",path,"index");
}catch(Exceptione){
e.printStackTrace();
}
//跳转到刚生成的html文件中
request.getRequestDispatcher("/index.htm").forward(request,response);
}
/**
*生成静态文件
*@paramrequest
*@paramftlftl文件
*@paramhtml生成html后的文件
*@paramfile存放ftl文件的路径
*@throwsException
*/
publicvoidfreemarker(HttpServletRequestrequest,Stringftl,
Stringhtml,Stringfile)throwsException{
Configurationcfg=newConfiguration();
//设置加载模板的路径
cfg.setServletContextForTemplateLoading(getServletContext(),"/"+file);
cfg.setEncoding(Locale.getDefault(),"GB18030");
//获得模板并设置编码
Templatetep=cfg.getTemplate(ftl);
tep.setEncoding("GB18303");
//新建输出,生成html文件
Writerout=newBufferedWriter(newOutputStreamWriter(newFileOutputStream(html),"GB18030"));
//设置值
Mapmap=newHashMap();
map.put("userName","wxj");
map.put("email","[email protected]");
//解析并输出
tep.process(map,out);
}
publicvoidinit()throwsServletException{
}
}
3.web.xml文件进行servlet配置。
Xml代码
<servlet>
<servlet-name>FreemarkerServletTest</servlet-name>
<servlet-class>com.servlet.FreemarkerServletTest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FreemarkerServletTest</servlet-name>
<url-pattern>/servlet/FreemarkerServletTest</url-pattern>
</servlet-mapping>
4.页面访问如下Url:
http://localhost:8080/freemarkerWeb/servlet/FreemarkerServletTest
输出结果如下:
Java代码
用户名:wxj
同时会在部署环境的目录下生成index.htm文件。