FreeMarker教程

一、什麼是模板引擎,爲什麼要用模板引擎

B/S程式設計中,常常有美工和程序員二個角色,他們具有不同專業技能:美工專注於表現——創建頁面、風格、佈局、效果等等可視元素;而程序員則忙於創建程式的商業流程,生成設計頁面要顯示的數據等等。

很多時候,要顯示的資料在設計的時候並不存在,它們一般是在運行時由程式產生的,比如執行價格不高於800NTUSB Disk”查詢的返回結果。這種技術需求產生了JSPScriptletJSP十分強大,但是也常常被濫用,並導致一些不良的後果

  1. 將邏輯和表現混合在一起。
  2. 破壞了美工和程序員職責的正常分解。
  3. 使JSP頁面難以閱讀和維護。

模板引擎就是爲了解決上面的問題而產生的。在設計HTML的時候,我們加入一些特定指令來指定要插入哪些數據,這些加了特殊指令的HTML或者其他文本,我們稱爲模板(Template)。而模板引擎會在輸出頁面時,用適當的數據替代這些代碼。

模板和嵌入JSPHTML是不同的,模板指令只有很有限的編程能力,可以避免混入商業邏輯。

二、FreeMarker與JSP、Velocity的對比

 FreeMarker優點:     

1.      不能編寫Java代碼,可以實現嚴格的MVC分離

2.    美工和技術的工作分離

3.      頁面是靜態化的,這樣方便搜索引擎的收錄

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插件的效果不太好


三、一個簡單的FreeMarkerDemo

1.導入Jar包:

     FreeMarker需要freemarker-2.3.19.jar包,Struts2裏面有這個Jar包。

2.編寫模板文件

         FreeMarker的模板文件的後綴名是ftl。這裏是我寫的一個Example.ftl,我把它放在WebRoot下的Template文件夾下。

[html] view plaincopy
  1. <html>               
  2.     <head>  
  3.         <title>Example</title>  
  4.     </head>   
  5.     <body >  
  6.         <h1>大家好,我的名字叫${name},我家住在${address},我今年${age}歲了!</h1>  
  7.     </body>  
  8. </html>  

3.模板的解析

模板需要被解析之後才能生成最終的文件,FreeMarker的數據模型也是在模板中配置的。

ExampleResolution.java

[java] view plaincopy
  1. publicclass ExampleResolution {  
  2.     publicvoid resolution(){  
  3.         Writer out = null;  
  4.         /** 
  5.          *創建Configuration對象 
  6.          *設置模板文件的基路徑 
  7.          *設置讀取模板的編碼方式 
  8.          */  
  9.         Configuration cfg = new Configuration();  
  10.     cfg.setServletContextForTemplateLoading(ServletActionContext.getServletContext(),"TemplateFiles");  
  11.         cfg.setDefaultEncoding("UTF-8");  
  12.         /** 
  13.          *創建FreeMarker的數據模型 
  14.          */  
  15.         Map root = newHashMap();  
  16.         root.put("name","李鑫龍");  
  17.         root.put("address","合肥市望江西路666號");  
  18.         root.put("age"23);  
  19.         /** 
  20.          *設置生成的模板的位置 
  21.          *合併數據模型與模板 
  22.          *生成最終的html頁面 
  23.          */  
  24.         try {       
  25.             Template template = cfg.getTemplate("Example.ftl");  
  26.             String path = ServletActionContext.getServletContext().getRealPath("/");  
  27.             File file = new File(path +"example.html");  
  28.             out = new BufferedWriter(new OutputStreamWriter(newFileOutputStream(file)));  
  29.             template.process(root, out);  
  30.         } catch (IOException e) {  
  31.             e.printStackTrace();  
  32.         } catch (TemplateException e) {  
  33.             e.printStackTrace();  
  34.         }finally{  
  35.             try {  
  36.                 out.flush();  
  37.                 out.close();  
  38.             } catch (IOException e) {  
  39.                 e.printStackTrace();  
  40.             }  
  41.         }  
  42.     }  
  43. }  

4.Action配置

[java] view plaincopy
  1. publicclass ServiceActionimplements Action {  
  2.     @Override  
  3.     public String execute()throws Exception {  
  4.         ExampleResolution er = new ExampleResolution();  
  5.         er.resolution();  
  6.         return Action.SUCCESS;  
  7.     }  
  8. }  

5.struts.xml配置

[html] view plaincopy
  1. <packagenamepackagename="default" namespace="/"extends="struts-default,json-default">  
  2.         <action name="example"class="com.lubby.action.ServiceAction">  
  3.             <resulttyperesulttype="redirect">/example.html</result>  
  4.         </action>  
  5. </package>  

6.效果顯示

[html] view plaincopy
  1. </html>  
  2.     <head>  
  3.         <title>Example</title>  
  4.     </head>  
  5.     <body >  
  6.         <h1>大家好,我的名字叫李鑫龍,我家住在合肥市望江西路666號,我今年23歲了!</h1>  
  7.     </body>  
  8. </html>  

四、FreeMarker的數據模型

 數據模型是樹型結構,可以任意複雜和深層次,如下面的例子:

[html] view plaincopy
  1. (root)  
  2.   |  
  3.   +- animals  
  4.   |   |  
  5.   |   +- mouse  
  6.   |   |  |    
  7.   |   |   +-size = "small"  
  8.   |   |  |    
  9.   |   |   +-price = 50  
  10.   |   |  
  11.   |   +- elephant  
  12.   |   |  |    
  13.   |   |   +-size = "large"  
  14.   |   |  |    
  15.   |   |   +-price = 5000  
  16.   |   |  
  17.   |   +- python  
  18.   |       |    
  19.   |       +- size = "medium"  
  20.   |       |    
  21.   |       +- price = 4999  
  22.   |  
  23.   +- test ="It is a test"  
  24.   |  
  25.   +- whatnot  
  26.       |  
  27.       +-because = "don't know"  

        類似於目錄的變量稱爲hashes,包含保存下級變量的唯一的查詢名字
        
類似於文件的變量稱爲scalars,保存單值
        scalars
保存的值有兩種類型:字符串(用引號括起,可以是單引號或雙引號)和數字(不要用引號將數字括起,這會作爲字符串處理)

  scalars的訪問從root開始,各部分用“.”分隔,如animals.mouse.price

         另外一種變量是sequences,和hashes類似,只是不使用變量名字,而使用數字索引,如下面的例子:

[html] view plaincopy
  1. (root)  
  2.   |  
  3.   +- animals  
  4.   |   |  
  5.   |   +- (1st)  
  6.   |   |   |  
  7.   |   |   +-name = "mouse"  
  8.   |   |   |  
  9.   |   |   +-size = "small"  
  10.   |   |   |  
  11.   |   |   +-price = 50  
  12.   |   |  
  13.   |   +- (2nd)  
  14.   |   |   |  
  15.   |   |   +-name = "elephant"  
  16.   |   |   |  
  17.   |   |   +-size = "large"  
  18.   |   |   |  
  19.   |   |   +-price = 5000  
  20.   |   |  
  21.   |   +- (3rd)  
  22.   |       |  
  23.   |       +- name = "python"  
  24.   |       |  
  25.   |       +- size = "medium"  
  26.   |       |  
  27.   |       +- price = 4999  
  28.   |  
  29.   +- whatnot  
  30.       |  
  31.       +- fruits  
  32.           |  
  33.           +- (1st)= "orange"  
  34.           |  
  35.           +- (2nd)= "banana"  

   這種對scalars的訪問使用索引,如animals[0].name        這種對scalars的訪問使用索引,如animals[0].name


五、模板的常用指令

   FreeMarker模板中可以包括下面幾個特定部分:
1.${…}
:稱爲interpolationsFreeMarker會在輸出時用實際值進行替代。

       1.1 ${name}可以取得rootkeynamevalue

       1.2 ${person.name}可以取得成員變量爲personname屬性

2.<#…>FTL標記(FreeMarker模板語言標記):類似於HTML標記,爲了與HTML標記區分

3.<@>:宏,自定義標籤

4.註釋:包含在<#---->(而不是<!---->)之間


.常用的FTL標記:

1if指令:用於判斷的指令

                     <#if (2>3)>

                                          二比三大

                            <#else>

                                     三比二大

                     </#if>

       2list指令:用來遍歷MapList

              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>

       3include指令:用來引入另一個另一個ftl模板或者html頁面

              <#include“TemplateFiles/example.ftl”>  

       4assign指令:用於爲該模板頁面創建或替換一個頂層變量

       變量爲String      <#assign address=”上海”>

            我家住在${address}

        結果:    我家住在上海

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

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

       結果:我的名字叫Tom,我今年20,我家住在上海

       5import指令:用於導入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內部的,也不會報錯


七、內建函數:

       使用方法類似於訪問散列的子變量,只是使用?代替.例如:${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")}


八、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!

九、通過Struts2設置type來訪問FreeMarker模板

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

[html] view plaincopy
  1. <span style="white-space:pre">  </span><html>  
  2.             <head>  
  3.                 <title>這是一個Example</title>  
  4.             </head>  
  5.             <body>  
  6.                 大家好,我的名字叫王媛媛!  
  7.             </body>  
  8.     </html>  

2.action配置

[java] view plaincopy
  1. public String example() throws Exception {  
  2.         System.out.println("example is requested.....");  
  3. ActionContext.getContext().getSession().put("name""劉德華");  
  4.         return Action.SUCCESS;  
  5.     }  

3.struts.xml配置 resulttype要設置爲freeMarker

[java] view plaincopy
  1. <action name="*" class="com.lubby.action.ServiceAction" method="{1}">  
  2.         <result type="freemarker">/WEB-INF/TemplateFiles/{1}.ftl</result>  
  3.     </action>  

3.struts.xml配置 resulttype要設置爲freeMarker

[java] view plaincopy
  1. <action name="*" class="com.lubby.action.ServiceAction" method="{1}">  
  2.         <result type="freemarker">/WEB-INF/TemplateFiles/{1}.ftl</result>  
  3.     </action>  
  4. <action name="*" class="com.lubby.action.ServiceAction" method="{1}">  
  5.         <result type="freemarker">/WEB-INF/TemplateFiles/{1}.ftl</result>  
  6.     </action>  

4.    效果顯示(通過session把值傳進去)

5.    使用type=“freemarker”與第一個demo的區別:

            第一個demo是先在action中調用解析方法生成一個html頁面,然後跳轉到這個生成的htm頁面。那麼以後訪問的話只需要直接訪問這個已經生成的html,無需解析,訪問速度回非常快。而使用struts2自帶的解析,每次訪問action都重新生成一個html頁面然後傳回瀏覽器。

            前者訪問的速度非常快,適合數據刷新頻率不高的地方。後者的訪問速度略遜於前者,適合數據刷新頻率高的地方。

十、利用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:請求的actionURL

colNameListjqGrid表所需要顯示的字段

colModelListjqGridcolModelList中的字段的英文名,和排序的類型

caption:表格的標題名

width:長度

height:高度

divIddivid


十一、利用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.參數的含義

       divIddivid

       type:圖表的類型     / line直線 / pie餅狀 / bar橫向條狀 / column柱狀圖

       title:圖表的標題

       subtitle:圖表的副標題

       yTitle:縱座標的標題

       function:當鼠標移到節點時,返回的信息    

       width:寬度

       height:高度


轉載自:http://blog.csdn.net/liu00614/article/details/8541193

發佈了29 篇原創文章 · 獲贊 13 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章