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

相關文章
相關標籤/搜索