freemarker的作用

当我们需要遍历json数据的时候,freemarker就起到了他的作用。在Java里使用的模板引擎有velocity、freemarker,至于velocity由于比较古老加之功能也不及freemarker那么强大使用的人群已经很少了。

freemarker是一种与web容器无关的技术,应用并不局限于页面。使用java开发出来的模板引擎。

freemarker的运行原理

  1. 初始化freemarker配置实例
  2. 创建数据模型
  3. 加载模板文件
  4. 显示生成后的数据

说完原理我们来看看代码

package com.mohan;  
  
import java.io.*;  
import java.util.*;  
  
import freemarker.template.Configuration;  
import freemarker.template.Template;  
  
public class FirstFreemarker {  
  
    public static void main(String[] args) throws Exception {  
        //创建freemarker配置实例  
        Configuration config=new Configuration();  
        config.setDirectoryForTemplateLoading(new File("template"));  
        //创建数据模型  
        Map<String,String> m=new HashMap<String,String>();  
        m.put("name", "mohan");  
        //加载模板文件  
        Template t=config.getTemplate("index.ftl");  
        //显示生成后的数据  
        Writer w=new OutputStreamWriter(System.out);  
        t.process(m, w);  
        w.close();  
    }  
  
} 

运行结果: hello ,mohan

freemarker不仅仅只能做这么点事情,它还可以包含数据类型、条件判断、数据遍历、内建函数等,

package com.mohan;  
  
import java.io.File;  
import java.io.OutputStreamWriter;  
import java.io.Writer;  
import java.util.ArrayList;  
import java.util.Date;  
import java.util.HashMap;  
import java.util.List;  
import java.util.Map;  
import java.util.Random;  
  
import freemarker.template.Configuration;  
import freemarker.template.Template;  
  
public class UseIf {  
    public static void main(String[] args) throws Exception {  
        //创建freemarker配置实例  
        Configuration config=new Configuration();  
        config.setDirectoryForTemplateLoading(new File("template"));  
        //创建数据模型  
        Map<String,Object> m=new HashMap<String,Object>();  
        m.put("score",  new Random().nextInt(100));  
          
        UserInfo u1=new UserInfo();  
        u1.setName("不知火舞");  
        u1.setPassword("123456");  
        UserInfo u2=new UserInfo();  
        u2.setName("路飞");  
        u2.setPassword("5777");  
        List<UserInfo> all=new ArrayList<UserInfo>();  
        all.add(u2);  
        all.add(u1);  
        m.put("userList", all);  
        m.put("time", new Date());  
        m.put("str", "北京,上海,深圳");  
        //加载模板文件  
        Template t=config.getTemplate("useif.ftl");  
        //显示生成后的数据  
        Writer w=new OutputStreamWriter(System.out);  
        t.process(m, w);  
        w.close();  
  
    }  
} 
-------------if语句的使用----------------  
<#if score gte 60>  
 及格  
<#elseif score gte 80&&score lte 90>  
良好  
<#else>  
高材生  
</#if>  
--------------空值判断、默认值---------------  
${name!"未定义"}  
--------------判断值是否存在------------  
<#if name??>  
  name存在  
<#else>  
 name不存在  
</#if>  
-------------使用list遍历数据--------------  
<#list userList as user>  
<#if  user_has_next> 最后一组:${user.name}-${user.password}<#else>${user.name}-${user.password}</#if>  
</#list>  
-------------其他内建函数-----------------  
(1)日期格式化  
${time?string("yyyy-MM-dd")}  
(2)截取字符串  
${str?substring(0,2)}  
(2)indexof的使用  
${str?last_index_of(",")}  
(2)split的使用  
<#list "12,13,14,15"?split(",") as item>  
${item}  
</#list>  

freemarker宏指令

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

package com.mohan;  
  
import java.io.File;  
import java.io.IOException;  
import java.io.OutputStreamWriter;  
import java.io.Writer;  
import java.util.HashMap;  
import java.util.Map;  
  
import freemarker.template.Configuration;  
import freemarker.template.Template;  
  
public class UseMacro {  
  
    public static void main(String[] args) throws Exception {  
        //创建freemarker配置实例  
        Configuration config=new Configuration();  
        config.setDirectoryForTemplateLoading(new File("template"));  
        //创建数据模型  
        Map<String,Object> m=new HashMap<String,Object>();  
        m.put("type", "other");  
        m.put("num1", 2);  
        m.put("num2", 3);  
        //加载模板文件  
        Template t=config.getTemplate("macro.ftl");  
        //显示生成后的数据  
        Writer w=new OutputStreamWriter(System.out);  
        t.process(m, w);  
        w.close();  
  
    }  
  
}  

 

模板文件的内容如下:

[plain] view plain copy 在CODE上查看代码片派生到我的代码片
----------------------宏指令的使用 m1可以看成是方法的名称,num1、num2为入参----------------------  
<#macro m1 num1 num2>  
<#assign result=num1+num2>  
<h3>${result}</h3>  
</#macro>  
<@m1 5 6/>  
----------------------宏指令(嵌入式)-----------------  
<#macro m2>  
<h3><#nested></h3>  
</#macro>  
<@m2>hello world</@m2>

运行效果如下:<h3>11</h3>

                        <h3>hello world</h3>

ferrmarker其他指令

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

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

<#macro copyright date>  
  <p>Copyright (C) ${date}.</p>   
</#macro>  

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

struts2中使用freemarker

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

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

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

 

 

<servlet>  
        <servlet-name>freemarker</servlet-name>  
        <servlet-class>  
            freemarker.ext.servlet.FreemarkerServlet  
        </servlet-class>  
        <!--下面的配置freemarke的ftl文件的位置 -->  
        <init-param>  
            <param-name>TemplatePath</param-name>  
            <param-value>/</param-value>  
        </init-param>  
        <!-- 是否和服务器(tommcat)一起启动。-->  
        <load-on-startup>1</load-on-startup>  
    </servlet>  
  
    <servlet-mapping>  
        <servlet-name>freemarker</servlet-name>  
        <url-pattern>*.ftl</url-pattern>  
    </servlet-mapping>  
  
  
<servlet>  
  <!-- define a JspSupportServlet Object -->  
  <servlet-name>JspSupportServlet</servlet-name>  
  <servlet-class>org.apache.struts2.views.JspSupportServlet</servlet-class>  
  <!-- setting JspSupportServlet auto start -->  
  <load-on-startup>1</load-on-startup>  
 </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的文件,内容如下:

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE taglib

PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"

"http://java.sun.com/j2ee/dtds/web-jsptaglib_1_1.dtd">


<taglib>


<tlibversion>2.0</tlibversion>

<jspversion>1.1</jspversion>

<shortname>FreeMarker JSP Support</shortname>


<tag>

<name>template</name>

<tagclass>freemarker.ext.jsp.FreemarkerTag</tagclass>

<bodycontent>tagdependent</bodycontent>

<info>Allows evaluation of FreeMarker templates inside JSP</info>

<attribute>

<name>caching</name>

<required>false</required>

</attribute>

</tag>

</taglib>

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

 

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

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

(2)嵌入freemarker

 <fm:template>  
       freemarker语句  
</fm:template>

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

 

 

扩充freemarker内建函数

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

public class MyFmTag implements TemplateMethodModel  {  
      
    public Object exec(List param) throws TemplateModelException {  
        Object result=null;  
        if("save".equals(param.get(0).toString())){  
            //调用保存方法  
        }  
        return result;  
    } 

 使用的时候就像下面这样就ok了

 <#assign check= "org.lxh.util.MyFmTag"?new()/>
 <#assign result=check('save','xxx')/>

看原文:原文

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐