freemarker的使用心得

来源:互联网 发布:vb皮肤控件 skinsharp 编辑:程序博客网 时间:2024/05/29 14:04

freemarker目前虽然使用的公司不多,但是在某些时候就必须使用,当需要遍历json数据的时候,目前市面上的好多显示组件都达不到要求唯一能用的也就只有freemarker了。在Java里使用的模板引擎有velocity、freemarker,至于velocity由于比较古老加之功能也不及freemarker那么强大使用的人群已经很少了。这次打算系统性的分享我学习freemarker的心得。

一  第一个freemarker程序

freemarker是一种与web容器无关的技术,应用并不局限于页面。使用java开发出来的模板引擎。因此java中使用freemarker应该算得上是一个比较好的选择了

freemarker的运行原理总结起来就是如下四点:

(1)初始化freemarker配置实例

(2)创建数据模型

(3)加载模板文件

(4)显示生成后的数据

如果要使用freemarker要做的就是把freemarker的jar包放到lib或者构建路径下面就OK了,来看下面这段程序

[java] view plain copy
  1. package org.lxh;  
  2.   
  3. import java.io.*;  
  4. import java.util.*;  
  5.   
  6. import freemarker.template.Configuration;  
  7. import freemarker.template.Template;  
  8.   
  9. public class FirstFreemarker {  
  10.   
  11.     public static void main(String[] args) throws Exception {  
  12.         //创建freemarker配置实例  
  13.         Configuration config=new Configuration();  
  14.         config.setDirectoryForTemplateLoading(new File("template"));  
  15.         //创建数据模型  
  16.         Map<String,String> m=new HashMap<String,String>();  
  17.         m.put("name""cry");  
  18.         //加载模板文件  
  19.         Template t=config.getTemplate("index.ftl");  
  20.         //显示生成后的数据  
  21.         Writer w=new OutputStreamWriter(System.out);  
  22.         t.process(m, w);  
  23.         w.close();  
  24.     }  
  25.   
  26. }  
运行效果如下所示:


二  freemarker进阶

如果觉得freemarker的能力就这么点那就错了,freemarker还包含数据类型、条件判断、数据遍历、内建函数等,这些功能对日常开发已经足够,看下面这段程序

[java] view plain copy
  1. package org.lxh;  
  2.   
  3. import java.io.File;  
  4. import java.io.OutputStreamWriter;  
  5. import java.io.Writer;  
  6. import java.util.ArrayList;  
  7. import java.util.Date;  
  8. import java.util.HashMap;  
  9. import java.util.List;  
  10. import java.util.Map;  
  11. import java.util.Random;  
  12.   
  13. import freemarker.template.Configuration;  
  14. import freemarker.template.Template;  
  15.   
  16. public class UseIf {  
  17.     public static void main(String[] args) throws Exception {  
  18.         //创建freemarker配置实例  
  19.         Configuration config=new Configuration();  
  20.         config.setDirectoryForTemplateLoading(new File("template"));  
  21.         //创建数据模型  
  22.         Map<String,Object> m=new HashMap<String,Object>();  
  23.         m.put("score",  new Random().nextInt(100));  
  24.           
  25.         UserInfo u1=new UserInfo();  
  26.         u1.setName("仓木麻衣");  
  27.         u1.setPassword("123456");  
  28.         UserInfo u2=new UserInfo();  
  29.         u2.setName("柯南");  
  30.         u2.setPassword("654321");  
  31.         List<UserInfo> all=new ArrayList<UserInfo>();  
  32.         all.add(u2);  
  33.         all.add(u1);  
  34.         m.put("userList", all);  
  35.         m.put("time"new Date());  
  36.         m.put("str""北京,上海,杭州");  
  37.         //加载模板文件  
  38.         Template t=config.getTemplate("useif.ftl");  
  39.         //显示生成后的数据  
  40.         Writer w=new OutputStreamWriter(System.out);  
  41.         t.process(m, w);  
  42.         w.close();  
  43.   
  44.     }  
  45. }  

看下模板文件的内容:
[plain] view plain copy
  1. --------------if语句的使用----------------  
  2. <#if score gte 60>  
  3.  及格  
  4. <#elseif score gte 80&&score lte 90>  
  5. 良好  
  6. <#else>  
  7. 高材生  
  8. </#if>  
  9. --------------空值判断、默认值---------------  
  10. ${name!"未定义"}  
  11. --------------判断值是否存在------------  
  12. <#if name??>  
  13.   name存在  
  14. <#else>  
  15.  name不存在  
  16. </#if>  
  17. -------------使用list遍历数据--------------  
  18. <#list userList as user>  
  19. <#if  user_has_next> 最后一组:${user.name}-${user.password}<#else>${user.name}-${user.password}</#if>  
  20. </#list>  
  21. -------------其他内建函数-----------------  
  22. (1)日期格式化  
  23. ${time?string("yyyy-MM-dd")}  
  24. (2)截取字符串  
  25. ${str?substring(0,2)}  
  26. (2)indexof的使用  
  27. ${str?last_index_of(",")}  
  28. (2)split的使用  
  29. <#list "12,13,14,15"?split(",") as item>  
  30. ${item}  
  31. </#list>  

对于list的遍历有两个隐含变量用的比较多分别是_index  _has_next  ,详细的使用可以百度一下,真的很简单


三 freemarker宏指令

宏指令可以简单理解成在freemarker可以自己定义的公共方法,具体用途主要用于分页,来看下面的这个最简单的例子

[java] view plain copy
  1. package org.lxh;  
  2.   
  3. import java.io.File;  
  4. import java.io.IOException;  
  5. import java.io.OutputStreamWriter;  
  6. import java.io.Writer;  
  7. import java.util.HashMap;  
  8. import java.util.Map;  
  9.   
  10. import freemarker.template.Configuration;  
  11. import freemarker.template.Template;  
  12.   
  13. public class UseMacro {  
  14.   
  15.     public static void main(String[] args) throws Exception {  
  16.         //创建freemarker配置实例  
  17.         Configuration config=new Configuration();  
  18.         config.setDirectoryForTemplateLoading(new File("template"));  
  19.         //创建数据模型  
  20.         Map<String,Object> m=new HashMap<String,Object>();  
  21.         m.put("type""other");  
  22.         m.put("num1"2);  
  23.         m.put("num2"3);  
  24.         //加载模板文件  
  25.         Template t=config.getTemplate("macro.ftl");  
  26.         //显示生成后的数据  
  27.         Writer w=new OutputStreamWriter(System.out);  
  28.         t.process(m, w);  
  29.         w.close();  
  30.   
  31.     }  
  32.   
  33. }  

模板文件的内容如下:
[plain] view plain copy
  1. ----------------------宏指令的使用 m1可以看成是方法的名称,num1、num2为入参----------------------  
  2. <#macro m1 num1 num2>  
  3. <#assign result=num1+num2>  
  4. <h3>${result}</h3>  
  5. </#macro>  
  6. <@m1 5 6/>  
  7. ----------------------宏指令(嵌入式)-----------------  
  8. <#macro m2>  
  9. <h3><#nested></h3>  
  10. </#macro>  
  11. <@m2>hello world</@m2>  

运行效果如下:



四  其他指令

包含指令:<#include "test.txt"  />

import指令:<#import "b.ftl" as bb  />

[plain] view plain copy
  1. <#macro copyright date>  
  2.   <p>Copyright (C) ${date}.</p>   
  3. </#macro>   


当ftl文件比较多的时候,而且这些ftl有引用关系,这个时候import就可以大展拳脚了,如<@bb.copyright date="2010-2011" />

五  struts2中使用freemarker

struts2是不能直接使用freemarker的,如果一定要用可以:

 (1)解压struts2-core-X.X.X.jar文件,把在META-INF文件夹下面的struts-tags.tld文件复制到WEB-INF文件夹下。   freemarkjar导入到工程中

 (2)web.xml文件中配置freemark同时启动JSPSupportServlet.代码如下

[html] view plain copy
  1. <servlet>  
  2.         <servlet-name>freemarker</servlet-name>  
  3.         <servlet-class>  
  4.             freemarker.ext.servlet.FreemarkerServlet  
  5.         </servlet-class>  
  6.         <!--下面的配置freemarke的ftl文件的位置 -->  
  7.         <init-param>  
  8.             <param-name>TemplatePath</param-name>  
  9.             <param-value>/</param-value>  
  10.         </init-param>  
  11.         <!-- 是否和服务器(tommcat)一起启动。-->  
  12.         <load-on-startup>1</load-on-startup>  
  13.     </servlet>  
  14.   
  15.     <servlet-mapping>  
  16.         <servlet-name>freemarker</servlet-name>  
  17.         <url-pattern>*.ftl</url-pattern>  
  18.     </servlet-mapping>  
  19.   
  20.   
  21. <servlet>  
  22.   <!-- define a JspSupportServlet Object -->  
  23.   <servlet-name>JspSupportServlet</servlet-name>  
  24.   <servlet-class>org.apache.struts2.views.JspSupportServlet</servlet-class>  
  25.   <!-- setting JspSupportServlet auto start -->  
  26.   <load-on-startup>1</load-on-startup>  
  27.  </servlet>  

(3).在FreeMarker模板中使用assign指令导入标签库,这样在freemarker中就可以使用struts2的标签了

<#assign s=JspTaglibs["/WEB-INF/struts-tags.tld"] /> 注:这里我把struts-tags.tld放在WEB-INF下面

(4)在FreeMarker模板中使用struts标签

<@s;property value=""/>

注:struts使用freemarker要在result的节点加上type="freemarker"

对于这种做法有些时候不好用,freemarker也提供了在jsp页面使用freemarker的方法,同样的还是需要把freemarker的tld文件放在WEB-INF下面,这个文件如果找不到可以建一个叫fmtag.tld的文件,内容如下:

[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE taglib  
  3.         PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"  
  4.         "http://java.sun.com/j2ee/dtds/web-jsptaglib_1_1.dtd">  
  5.   
  6. <taglib>  
  7.   
  8.   <tlibversion>2.0</tlibversion>  
  9.   <jspversion>1.1</jspversion>  
  10.   <shortname>FreeMarker JSP Support</shortname>  
  11.   
  12.   <tag>  
  13.     <name>template</name>  
  14.     <tagclass>freemarker.ext.jsp.FreemarkerTag</tagclass>  
  15.     <bodycontent>tagdependent</bodycontent>  
  16.     <info>Allows evaluation of FreeMarker templates inside JSP</info>  
  17.     <attribute>  
  18.       <name>caching</name>  
  19.       <required>false</required>  
  20.     </attribute>  
  21.   </tag>  
  22. </taglib>  

接下来看看在jsp中怎么使用freemarker

(1)jsp页面引入freemarker标签库

<%@ taglib prefix="fm" uri="/WEB-INF/fmtag.tld" %>

(2)嵌入freemarker

[plain] view plain copy
  1.  <fm:template>  
  2.        freemarker语句  
  3. </fm:template>  

综合前面的情况无论怎么用是不是都很简单呢


六  扩充freemarker内建函数

freemarker虽然提供很多内建函数,但仍然有需要自定义的时候,freemarker也运行用户写自定义函数,如下所示:

[java] view plain copy
  1. public class MyFmTag implements TemplateMethodModel  {  
  2.       
  3.     public Object exec(List param) throws TemplateModelException {  
  4.         Object result=null;  
  5.         if("save".equals(param.get(0).toString())){  
  6.             //调用保存方法  
  7.         }  
  8.         return result;  
  9.     }  
  10.     //保存方法................  
  11. }  
 使用的时候就像下面这样就ok了 <#assign check= "org.lxh.util.MyFmTag"?new()/>
 <#assign result=check('save','xxx')/>
原创粉丝点击