FreeMarker教程

1、什么是模板引擎,为何要用模板引擎html

在B/S程式设计中,经常有美工和程序员二个角色,他们具备不一样专业技能:美工专一于表现——建立页面、风格、布局、效果等等可视元素;而程序员则忙于建立程式的商业流程,生成设计页面要显示的数据等等。java

不少时候,要显示的资料在设计的时候并不存在,它们通常是在运行时由程式产生的,好比执行“价格不高于800NT的USB Disk”查询的返回结果。这种技术需求产生了JSP等Scriptlet,JSP十分强大,可是也经常被滥用,并致使一些不良的后果python

  1. 将逻辑和表现混合在一块儿。
  2. 破坏了美工和程序员职责的正常分解。
  3. 使JSP页面难以阅读和维护。

模板引擎就是为了解决上面的问题而产生的。在设计HTML的时候,咱们加入一些特定指令来指定要插入哪些数据,这些加了特殊指令的HTML或者其余文本,咱们称为模板(Template)。而模板引擎会在输出页面时,用适当的数据替代这些代码。程序员

模板和嵌入JSP的HTML是不一样的,模板指令只有颇有限的编程能力,能够避免混入商业逻辑。数据库

2、FreeMarker与JSP、Velocity的对比编程

 FreeMarker优势:json

  1. 不能编写Java代码,能够实现严格的MVC分离浏览器

  2. 美工和技术的工做分离session

  3. 页面是静态化的,这样方便搜索引擎的收录app

  4. 模板能够存在数据库,能够实现cms定制功能

  5. 性能不错,页面显示的速度很是快,省去了JSP编译的过程

  6. 内置许多功能强大的标记、以及大量经常使用的函数

  7. 带有宏定义(macro)功能,相似于JSP自定义标签,可是更加简单方便

  8. 支持JSP标签

  9. Struts2对其支持效果不错

  10.不必定非要在Servlet中去实现      

FreeMarker缺点

  1. 性能没有Velocity高,学习起来没有Velocity简单

  2. 须要花费时间从新学习

  3. FreeMarker中不能读取值为null的变量,会报错,必需要设置默认值或者判断

  4. 模板修改以后,若是没有更新模板生成的HTML,会看到过时的页面

  5. MyEclipseIDE插件的效果不太好

3、一个简单的FreeMarkerDemo

1.导入Jar包:

     FreeMarker须要freemarker-2.3.19.jar包,Struts2里面有这个Jar包。

2.编写模板文件

     FreeMarker的模板文件的后缀名是ftl。这里是我写的一个Example.ftl,我把它放在WebRoot下的Template文件夹下。

<html>             
    <head>
        <title>Example</title>
    </head> 
    <body >
        <h1>你们好,个人名字叫${name},我家住在${address},我今年${age}岁了!</h1>
    </body>
</html>

3.模板的解析

模板须要被解析以后才能生成最终的文件,FreeMarker的数据模型也是在模板中配置的。

ExampleResolution.java

publicclass ExampleResolution {
    publicvoid resolution(){
        Writer out = null;
        /**
         *建立Configuration对象
         *设置模板文件的基路径
         *设置读取模板的编码方式
         */
        Configuration cfg = new Configuration();
    cfg.setServletContextForTemplateLoading(ServletActionContext.getServletContext(),"TemplateFiles");
        cfg.setDefaultEncoding("UTF-8");
        /**
         *建立FreeMarker的数据模型
         */
        Map root = newHashMap();
        root.put("name","李鑫龙");
        root.put("address","合肥市望江西路666号");
        root.put("age", 23);
        /**
         *设置生成的模板的位置
         *合并数据模型与模板
         *生成最终的html页面
         */
        try {     
            Template template = cfg.getTemplate("Example.ftl");
            String path = ServletActionContext.getServletContext().getRealPath("/");
            File file = new File(path +"example.html");
            out = new BufferedWriter(new OutputStreamWriter(newFileOutputStream(file)));
            template.process(root, out);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TemplateException e) {
            e.printStackTrace();
        }finally{
            try {
                out.flush();
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

4.Action配置

publicclass ServiceActionimplements Action {
    @Override
    public String execute()throws Exception {
        ExampleResolution er = new ExampleResolution();
        er.resolution();
        return Action.SUCCESS;
    }
}

5.struts.xml配置

<packagename="default" namespace="/"extends="struts-default,json-default">
        <action name="example"class="com.lubby.action.ServiceAction">
            <resulttype="redirect">/example.html</result>
        </action>
</package>

6.效果显示

</html>
    <head>
        <title>Example</title>
    </head>
    <body >
        <h1>你们好,个人名字叫李鑫龙,我家住在合肥市望江西路666号,我今年23岁了!</h1>
    </body>
</html>

4、FreeMarker的数据模型

数据模型是树型结构,能够任意复杂和深层次,以下面的例子:

(root)
  |
  +- animals
  |   |
  |   +- mouse
  |   |  |  
  |   |   +-size = "small"
  |   |  |  
  |   |   +-price = 50
  |   |
  |   +- elephant
  |   |  |  
  |   |   +-size = "large"
  |   |  |  
  |   |   +-price = 5000
  |   |
  |   +- python
  |       |  
  |       +- size = "medium"
  |       |  
  |       +- price = 4999
  |
  +- test ="It is a test"
  |
  +- whatnot
      |
      +-because = "don't know"

相似于目录的变量称为hashes,包含保存下级变量的惟一的查询名字

相似于文件的变量称为scalars,保存单值

scalars保存的值有两种类型:字符串(用引号括起,能够是单引号或双引号)和数字(不要用引号将数字括起,这会做为字符串处理)

对scalars的访问从root开始,各部分用“.”分隔,如animals.mouse.price

(root)
  |
  +- animals
  |   |
  |   +- (1st)
  |   |   |
  |   |   +-name = "mouse"
  |   |   |
  |   |   +-size = "small"
  |   |   |
  |   |   +-price = 50
  |   |
  |   +- (2nd)
  |   |   |
  |   |   +-name = "elephant"
  |   |   |
  |   |   +-size = "large"
  |   |   |
  |   |   +-price = 5000
  |   |
  |   +- (3rd)
  |       |
  |       +- name = "python"
  |       |
  |       +- size = "medium"
  |       |
  |       +- price = 4999
  |
  +- whatnot
      |
      +- fruits
          |
          +- (1st)= "orange"
          |
          +- (2nd)= "banana"

这种对scalars的访问使用索引,如animals[0].name        这种对scalars的访问使用索引,如animals[0].name

另一种变量是sequences,和hashes相似,只是不使用变量名字,而使用数字索引,以下面的例子:

5、模板的经常使用指令

在FreeMarker模板中能够包括下面几个特定部分:

1.${…}:称为interpolations,FreeMarker会在输出时用实际值进行替代。

  1.1 ${name}能够取得root中key为name的value。

  1.2 ${person.name}能够取得成员变量为person的name属性

2.<#…>:FTL标记(FreeMarker模板语言标记):相似于HTML标记,为了与HTML标记区分

3.<@>:宏,自定义标签

4.注释:包含在<#--和-->(而不是<!--和-->)之间

六.经常使用的FTL标记:

一、if指令:用于判断的指令

<#if (2>3)>

       二比三大

<#else>

        三比二大

</#if>

2、list指令:用来遍历Map和List的

2.1遍历List的数据

<#list arrList as item>

        ${item}

</#list>

2.2遍历Map的数据

<#listmyMap?keys as item>

     ${item}-${myMap[item]}

 </#list>

2.3 item_has_next:判断list是否还有值,

<#listarrList as item>

     <#if item_has_next>more,

           <#else>end.

      </#if>                         

</#list>

2.4<#break />指令能够跳出循环

<#listarrList as item>

      <#if!item_has_nex>end. <#break />

      </#if>

       more,

</#list>

3、include指令:用来引入另外一个另外一个ftl模板或者html页面

<#include“TemplateFiles/example.ftl”>  

4、assign指令:用于为该模板页面建立或替换一个顶层变量

变量为String      <#assign address=”上海”>

    我家住在${address}

结果:    我家住在上海

变量为map:  <#assign person={"name":"Tom","age":20,"address":"上海"} >

个人名字叫${person.name},我今年${person.age},我家住在${person.address}

结果:个人名字叫Tom,我今年20,我家住在上海

5、import指令:用于导入FreeMarker模板中的全部变量,并将该变量放置在指定的Map对象中。

<#import "/libs/mylib.ftl"as my>

6.判断为空: FreeMarker默认是不容许值为空或者值不存在的,不然必定会报错。因此咱们须要一些方法来判断是否为空或者是否存在

方法一:<h1>Welcome${user!"Anonymous"}!</h1>

        当user为空或者不存在会默认为Anonymous.

        ${user!}这个当user不存在或为空时候,不会报错,也不会输出。

方法二:<#if name??>name is exist</#if> 

        这里会先判断,若name为空或不存在则不会执行if内部的,也不会报错

7、内建函数:

  使用方法相似于访问散列的子变量,只是使用?代替.例如:${test?upper_case?html}经常使用的内建函数列举以下:

       ?html:   html字符转义

       ?cap_first: 字符串的第一个字母变为大写形式

       ?lower_case :字符串的小写形式

       ?upper_case :字符串的大写形式

       ?trim:去掉字符串首尾的空格

       ?substring:截字符串

       ?lenth: 取长度

       ?size: 序列中元素的个数

       ?int : 数字的整数部分(好比- 1.9?int 就是- 1)

       ?replace:字符串替换

       一些示例:

       ${username?[0,10]}

       ${appHtml?replace('<@person.component/>', "AK47test")}

8、FreeMarker macro(宏)的使用

1.example1.ftl 设置宏

<#macroname >

     个人名字叫作${name}!

</#macro>

2.example2.ftl 调用example1.ftl的宏

<#inclue“example1.ftl”>

<#macroname=”王晓乐”></#macro>

最终能够在example2.ftl模板生成的页面中获得:

个人名字叫作王晓乐!

3.关于关于嵌套指令<#nested>

<#macrogreet>

              <#nested>

              <#nested>          

</#macro>

调用:<@greet>hello!</@greet>

结果:  hello!

              hello!

9、经过Struts2设置type来访问FreeMarker模板

1.WEB-INF/TemplateFiles/example.ftl模板文件

<span style="white-space:pre">    </span><html>
            <head>
                <title>这是一个Example</title>
            </head>
            <body>
                你们好,个人名字叫王媛媛!
            </body>
    </html>

2.action配置

public String example() throws Exception {
        System.out.println("example is requested.....");
        ActionContext.getContext().getSession().put("name", "刘德华");
        return Action.SUCCESS;
}

3.struts.xml配置 result的type要设置为freeMarker

<action name="*" class="com.lubby.action.ServiceAction" method="{1}">
        <result type="freemarker">/WEB-INF/TemplateFiles/{1}.ftl</result>
</action>

3.struts.xml配置 result的type要设置为freeMarker

<action name="*" class="com.lubby.action.ServiceAction" method="{1}">
        <result type="freemarker">/WEB-INF/TemplateFiles/{1}.ftl</result>
</action>
<action name="*" class="com.lubby.action.ServiceAction" method="{1}">
        <result type="freemarker">/WEB-INF/TemplateFiles/{1}.ftl</result>
</action>

4.    效果显示(经过session把值传进去)

5.    使用type=“freemarker”与第一个demo的区别:

    第一个demo是先在action中调用解析方法生成一个html页面,而后跳转到这个生成的htm页面。那么之后访问的话只须要直接访问这个已经生成的html,无需解析,访问速度回很是快。而使用struts2自带的解析,每次访问action都从新生成一个html页面而后传回浏览器。

    前者访问的速度很是快,适合数据刷新频率不高的地方。后者的访问速度略逊于前者,适合数据刷新频率高的地方。

10、利用macro简单封装的jqGrid的使用方法

1.macro名和参数的调用Demo

<@myjqgrid url="jqgridtest.action" colNameList=["来电号码","业务类型","编号"] colModelList=[["customer","string"],["bussiness","string"],["id","int"]] caption="jqgrid测试三" width="500" height="250" divId="jqgridOne" />

2.参数的含义

url:请求的action的URL

colNameList:jqGrid表所须要显示的字段

colModelList:jqGrid中colModelList中的字段的英文名,和排序的类型

caption:表格的标题名

width:长度

height:高度

divId:div的id名

11、利用macro简单封装的highcharts的使用方法

1.macro名和参数的调用Demo

<@highcharts divId="container1" type="column" title="2012年气温变化表一" subtitle="合肥气象局提供"yTitle="温度 (°C)" function=" return'<b>'+ this.series.name +'</b><br/>'+ this.x +': '+ this.y+'°C';" width="500"height="300"/>

2.参数的含义

      divId:div的id名

      type:图表的类型     / line直线 / pie饼状 / bar横向条状 / column柱状图

      title:图表的标题

      subtitle:图表的副标题

      yTitle:纵坐标的标题

      function:当鼠标移到节点时,返回的信息    

      width:宽度

      height:高度

本文转自:http://blog.csdn.net/liu00614/article/details/8541193

相关文章
相关标签/搜索