FreeMarker 快速入門
參考:https://www.cnblogs.com/itdragon/p/7750903.html
FreeMarker 快速入門
FreeMarker是一個很值得去學習的模版引擎。它是基於模板檔案生成其他文字的通用工具。本章內容通過如何使用FreeMarker生成Htmlweb頁面 和 程式碼自動生成工具來快速瞭解FreeMarker。
1 簡介
FreeMarker是一款用java語言編寫的模版引擎,它雖然不是web應用框架,但它很合適作為web應用框架的一個元件。
特點:
1. 輕量級模版引擎,不需要Servlet環境就可以很輕鬆的嵌入到應用程式中
2. 能生成各種文字,如html,xml,java,等
3. 入門簡單,它是用java編寫的,很多語法和java相似
工作原理:(借用網上的圖片)
2 FreeMarker 程式
這裡通過模擬簡單的程式碼自動生產工具來感受第一個FreeMarker程式。
專案目錄結構
專案建立流程
第一步:建立一個maven專案匯入 FreeMarker jar 包
第二步:建立目錄templates,並建立一個FreeMarker模版檔案 hello.ftl
第三步:建立一個執行FreeMarker模版引擎的 FreeMarkerDemo.java檔案
第四步:執行main方法後重新整理專案
pom.xml檔案 ,maven專案核心檔案,管理 jar包。
1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 3 <modelVersion>4.0.0</modelVersion> 4 <groupId>com.freemark</groupId> 5 <artifactId>freemarkerStudy</artifactId> 6 <version>0.0.1-SNAPSHOT</version> 7 <packaging>war</packaging> 8 9 <dependencies> 10 <dependency> 11 <groupId>org.freemarker</groupId> 12 <artifactId>freemarker</artifactId> 13 <version>2.3.20</version> 14 </dependency> 15 </dependencies> 16 17 </project>
hello.ftl FreeMarker基本語法: ${xxx}xxx 相當於佔位符,java後臺給xxx賦值後,再通過${}輸出
1 package ${classPath}; 2 3 public class ${className} { 4 5 public static void main(String[] args) { 6 System.out.println("${helloWorld}"); 7 } 8 9 }
FreeMarkerDemo.java核心方法,使用 FreeMarker模版引擎。
1 package com.freemark.hello; 2 3 import java.io.BufferedWriter; 4 import java.io.File; 5 import java.io.FileOutputStream; 6 import java.io.OutputStreamWriter; 7 import java.io.Writer; 8 import java.util.HashMap; 9 import java.util.Map; 10 11 import freemarker.template.Configuration; 12 import freemarker.template.Template; 13 14 /** 15 * 最常見的問題: 16 * java.io.FileNotFoundException: xxx does not exist. 解決方法:要有耐心 17 * FreeMarker jar 最新的版本(2.3.23)提示 Configuration 方法被棄用 18 * 程式碼自動生產基本原理: 19 * 資料填充 freeMarker 佔位符 20 */ 21 public class FreemarkerDemo { 22 23 private static final String TEMPLATE_PATH = "src/main/java/com/freemark/hello/templates"; 24 private static final String CLASS_PATH = "src/main/java/com/freemark/hello"; 25 26 public static void main(String[] args) { 27 // step1 建立freeMarker配置例項 28 Configuration configuration = new Configuration(); 29 Writer out = null; 30 try { 31 // step2 獲取模版路徑 32 configuration.setDirectoryForTemplateLoading(new File(TEMPLATE_PATH)); 33 // step3 建立資料模型 34 Map<String, Object> dataMap = new HashMap<String, Object>(); 35 dataMap.put("classPath", "com.freemark.hello"); 36 dataMap.put("className", "AutoCodeDemo"); 37 dataMap.put("helloWorld", "通過簡單的 <程式碼自動生產程式> 演示 FreeMarker的HelloWorld!"); 38 // step4 載入模版檔案 39 Template template = configuration.getTemplate("hello.ftl"); 40 // step5 生成資料 41 File docFile = new File(CLASS_PATH + "\\" + "AutoCodeDemo.java"); 42 out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(docFile))); 43 // step6 輸出檔案 44 template.process(dataMap, out); 45 System.out.println("^^^^^^^^^^^^^^^^^^^^^^^^AutoCodeDemo.java 檔案建立成功 !"); 46 } catch (Exception e) { 47 e.printStackTrace(); 48 } finally { 49 try { 50 if (null != out) { 51 out.flush(); 52 } 53 } catch (Exception e2) { 54 e2.printStackTrace(); 55 } 56 } 57 } 58 59 }
執行程式後重新整理專案,會發現多了一個AutoCodeDemo.java類。不僅僅是java類,xml也是可以。筆者就是通過FreeMarker做了一個簡易的工具類,公司的一個標準管理頁面及其增刪改查等功能,以及相關的配置檔案(十三個檔案),一個回車就全部自動生成(偷懶ing)。
3FreeMarker語法
語法和java很類似,其中巨集的概念可能比較陌生,先上程式碼
stringFreeMarker.ftl FreeMarker主要核心知識點
字串輸出: ${"Hello ${name} !"} / ${"Hello " + name + " !"} <#assign cname=r"特殊字元完成輸出(http:\www.baidu.com)"> ${cname} 字串擷取 : 通過下標直接獲取下標對應的字母: ${name[2]} 起點下標..結尾下標擷取字串:${name[0..5]} 算數運算: <#-- 支援"+"、"-"、"*"、"/"、"%"運算子 --> <#assign number1 = 10> <#assign number2 = 5> "+" : ${number1 + number2} "-" : ${number1 - number2} "*" : ${number1 * number2} "/" : ${number1 / number2} "%" : ${number1 % number2} 比較運算子: <#if number1 + number2 gte 12 || number1 - number2 lt 6> "*" : ${number1 * number2} <#else> "/" : ${number1 / number2} </#if> 內建函式: <#assign data = "abcd1234"> 第一個字母大寫:${data?cap_first} 所有字母小寫:${data?lower_case} 所有字母大寫:${data?upper_case} <#assign floatData = 12.34> 數值取整數:${floatData?int} 獲取集合的長度:${users?size} 時間格式化:${dateTime?string("yyyy-MM-dd")} 空判斷和物件集合: <#if users??> <#list users as user > ${user.id} - ${user.name} </#list> <#else> ${user!"變數為空則給一個預設值"} </#if> Map集合: <#assign mapData={"name":"程式設計師", "salary":15000}> 直接通過Key獲取 Value值:${mapData["name"]} 通過Key遍歷Map: <#list mapData?keys as key> Key: ${key} - Value: ${mapData[key]} </#list> 通過Value遍歷Map: <#list mapData?values as value> Value: ${value} </#list> List集合: <#assign listData=["ITDragon", "blog", "is", "cool"]> <#list listData as value>${value} </#list> include指令: 引入其他檔案:<#include "otherFreeMarker.ftl" /> macro巨集指令: <#macro mo> 定義無引數的巨集macro--${name} </#macro> 使用巨集macro: <@mo /> <#macro moArgs a b c> 定義帶引數的巨集macro-- ${a+b+c} </#macro> 使用帶引數的巨集macro: <@moArgs a=1 b=2 c=3 /> 名稱空間: <#import "otherFreeMarker.ftl" as otherFtl> ${otherFtl.otherName} <@otherFtl.addMethod a=10 b=20 /> <#assign otherName="修改otherFreeMarker.ftl中的otherName變數值"/> ${otherFtl.otherName} <#assign otherName="修改otherFreeMarker.ftl中的otherName變數值" in otherFtl /> ${otherFtl.otherName}
otherFreeMarker.ftl為了測試名稱空間 和include指令的FreeMarker檔案
其他FreeMarker檔案 <#macro addMethod a b > result : ${a + b} </#macro> <#assign otherName="另外一個FreeMarker的變數">
FreeMarkerDemo.java核心方法
1 package com.freemark.demo; 2 3 import java.util.List; 4 import java.io.BufferedWriter; 5 import java.io.File; 6 import java.io.FileOutputStream; 7 import java.io.OutputStreamWriter; 8 import java.io.Writer; 9 import java.util.Date; 10 import java.util.ArrayList; 11 import java.util.HashMap; 12 import java.util.Map; 13 14 import freemarker.template.Configuration; 15 import freemarker.template.Template; 16 17 public class FreeMarkerDemo { 18 19 private static final String TEMPLATE_PATH = "src/main/java/com/freemark/demo/templates"; 20 21 public static void main(String[] args) { 22 // step1 建立freeMarker配置例項 23 Configuration configuration = new Configuration(); 24 Writer out = null; 25 try { 26 // step2 獲取模版路徑 27 configuration.setDirectoryForTemplateLoading(new File(TEMPLATE_PATH)); 28 // step3 建立資料模型 29 Map<String, Object> dataMap = new HashMap<String, Object>(); 30 dataMap.put("name", "itdragon部落格"); 31 dataMap.put("dateTime", new Date()); 32 33 List<User> users = new ArrayList<User>(); 34 users.add(new User(1, "ITDragon 部落格")); 35 users.add(new User(2, "歡迎")); 36 users.add(new User(3, "You!")); 37 dataMap.put("users", users); 38 // step4 載入模版檔案 39 Template template = configuration.getTemplate("stringFreeMarker.ftl"); 40 // step5 生成資料 41 out = new OutputStreamWriter(System.out); 42 // step6 輸出檔案 43 template.process(dataMap, out); 44 } catch (Exception e) { 45 e.printStackTrace(); 46 } finally { 47 try { 48 if (null != out) { 49 out.flush(); 50 } 51 } catch (Exception e2) { 52 e2.printStackTrace(); 53 } 54 } 55 } 56 57 }
User.java為了測試FreeMarker的集合物件
1 package com.freemark.demo; 2 3 public class User { 4 5 private Integer id; 6 private String name; 7 8 public User() { 9 } 10 11 public User(Integer id, String name) { 12 this.id = id; 13 this.name = name; 14 } 15 16 public Integer getId() { 17 return id; 18 } 19 20 public void setId(Integer id) { 21 this.id = id; 22 } 23 24 public String getName() { 25 return name; 26 } 27 28 public void setName(String name) { 29 this.name = name; 30 } 31 32 @Override 33 public String toString() { 34 return "User [id=" + id + ", name=" + name + "]"; 35 } 36 37 }
最後的列印結果
字串輸出: Hello itdragon部落格 ! / Hello itdragon部落格 ! 特殊字元完成輸出(http:\www.baidu.com) 字串擷取 : 通過下標直接獲取下標對應的字母: d 起點下標..結尾下標擷取字串:itdrag 算數運算: "+" : 15 "-" : 5 "*" : 50 "/" : 2 "%" : 0 比較運算子: "*" : 50 內建函式: 第一個字母大寫:Abcd1234 所有字母小寫:abcd1234 所有字母大寫:ABCD1234 數值取整數:12 獲取集合的長度:3 時間格式化:2017-10-29 空判斷和物件集合: 1 - ITDragon 部落格 2 - 歡迎 3 - You! Map集合: 直接通過Key獲取 Value值:程式設計師 通過Key遍歷Map: Key: name - Value: 程式設計師 Key: salary - Value: 15,000 通過Value遍歷Map: Value: 程式設計師 Value: 15,000 List集合: ITDragon blog is cool include指令: 其他FreeMarker檔案 macro巨集指令: 使用巨集macro: 定義無引數的巨集macro--itdragon部落格 使用帶引數的巨集macro: 定義帶引數的巨集macro-- 6 名稱空間: 另外一個FreeMarker的變數 result : 30 另外一個FreeMarker的變數 修改otherFreeMarker.ftl中的otherName變數值
語法詳解
資料型別
和java不同,FreeMarker不需要定義變數的型別,直接賦值即可。
字串:value = "xxxx" 。如果有特殊字元 string = r"xxxx" 。單引號和雙引號是一樣的。
數值:value = 1.2。數值可以直接等於,但是不能用科學計數法。
布林值:trueor false。
List集合:list = [1,2,3] ;list=[1..100]表示 1到 100的集合,反之亦然。
Map集合:map = {"key" : "value" , "key2" : "value2"},key必須是字串哦!
實體類:和EL表示式差不多,直接點出來。
字串操作
字串連線:可以直接巢狀${"hello , ${name}"} ; 也可以用加號${"hello , " + name}
字串擷取:string[index]。index可以是一個值,也可以是形如 0..2表示下標從0開始,到下標為2結束。一共是三個數。
比較運算子
== (等於),!= (不等於),gt(大於),gte(大於或者等於),lt(小於),lte(小於或者等於)。不建議用 >,< 可能會報錯!
一般和if 配合使用
內建函式
FreeMarker提供了一些內建函式來轉換輸出,其結構:變數?內建函式,這樣就可以通過內建函式來轉換輸出變數。
1. html: 對字串進行HTML編碼;
2. cap_first: 使字串第一個字母大寫;
3. lower_case: 將字串轉成小寫;
4. upper_case: 將字串轉成大寫;
5. size: 獲得集合中元素的個數;
6. int: 取得數字的整數部分。
變數空判斷
! 指定缺失變數的預設值;一般配置變數輸出使用
?? 判斷變數是否存在。一般配合if使用 <#if value??></#if>
巨集指令
可以理解為java的封裝方法,供其他地方使用。巨集指令也稱為自定義指令,macro指令
語法很簡單:<#macro val >宣告macro </#macro>;使用macro <@val />
名稱空間
可以理解為java的import語句,為避免變數重複。一個重要的規則就是:路徑不應該包含大寫字母,使用下劃線_分隔詞語,myName --> my_name
語法很簡單:<#import "xxx.ftl" asval>
其他沒有說明的語法是因為和java一樣,沒什麼特別之處。所以沒有列出來。
4 FreeMarker Web
這裡是和SpringMVC整合的,SpringMVC的配置就不多說了,筆者也寫過相關的文章,同時也會提供原始碼
匯入相關的jar pom.xml
<!-- freeMarker start --> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.20</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>4.1.4.RELEASE</version> </dependency> </dependencies> <!-- freeMarker end -->
springmvc的配置檔案:
<!-- 整合Freemarker --> <!-- 放在InternalResourceViewResolver的前面,優先找freemarker --> <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"> <property name="templateLoaderPath" value="/WEB-INF/views/templates"/> </bean> <bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver"> <property name="prefix" value=""/> <property name="suffix" value=".ftl"/> <property name="contentType" value="text/html; charset=UTF-8"/> </bean>
Controller 層
import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class HelloFreeMarkerController { @RequestMapping("/helloFreeMarker") public String helloFreeMarker(Model model) { model.addAttribute("name","ITDragon部落格"); return "helloFreeMarker"; } }
最後是Freemarker檔案
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>FreeMarker Web</title> </head> <body> <h1>Hello ${name} !</h1> </body> </html>
原始碼地址:https://gitee.com/itdragon/springmvc
5 小結
1.知道了FreeMarker是一塊模版引擎,可以生產xml,html,java等檔案
2.知道了FreeMarker檔案提供佔位符,java檔案提供資料,通過FreeMarker模版引擎生產有資料的頁面,文中是將資料放在Map中。web應用可以用setter/getter方法
3.知道了FreeMarker語法中字串的顯示特殊字元,擷取的操作。以及一些內建方法的使用
4.重點了解FreeMarker的空判斷知識點。判斷變數是否為空用 "??" ,如果變數為空設定預設值。如果不注意空問題,可能會出現黃色頁面的提示哦!
5.FreeMarker的巨集概念,名稱空間,引入檔案,給變數賦值,集合的遍歷等。
6. Freemarker 整合SpringMVC。
到這裡FreeMarker的入門就結束了,是不是很簡單。如果有什麼不對的地方,請指正!