一、freemarker介紹
- FreeMarker 是一款 模板引擎
- 即一種基于模板和要改變的資料, 并用來生成輸出文本(HTML網頁,電子郵件,組態檔,源代碼等)的通用工具, 它不是面向最終用戶的,而是一個Java類別庫,是一款程式員可以嵌入他們所開發產品的組件
- 模板撰寫為FreeMarker Template Language(FTL)
- 它是簡單的,專用的語言,不是像PHP那樣成熟的變成語言,那就意味著要準備資料在在真實編程語言中來顯示,比如資料庫查詢和業務運算,之后模板顯示以及準備好的資料,在模板中,可以更加專注于如何展現資料,而在模板之外可以專注于要展示什么資料

二、freemarker環境搭建&&快速入門
需要創建Spring Boot + Freemarker 工程用于測驗模板
2.1、創建測驗工程
-
創建一個freemark-demo的測驗工程用于freemarker的功能測驗與模板測驗
-
POM檔案如下所示
-
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.coolman</groupId> <artifactId>freemarker-demo</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--freemarker springboot starter--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency> <!-- lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> </project>
-
2.2、組態檔
-
application.yml檔案如下所示
-
server: port: 9527 spring: application: name: freemarker-demo # 指定服務名 freemarker: cache: false # 關閉快取,方便測驗 settings: template_update_delay: 0 #檢查模板更新延遲時間,設定為0表示立即檢查,如果時間大于0會有快取不方便進行模板測驗 suffix: .ftl #指定Freemarker模板檔案的后綴名 template-loader-path: classpath:/templates #指定模板檔案存放的位置
-
2.3、創建啟動類
-
啟動類如下所示
-
package com.coolman.freemarker; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class FreemarkerApplication { public static void main(String[] args) { SpringApplication.run(FreemarkerApplication.class, args); } }
-
2.4、創建模型類
-
在freemarker的測驗工程下創建模型型別用于測驗
-
package com.coolman.freemarker.model; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @AllArgsConstructor @NoArgsConstructor public class Person { private String name; private Integer age; }
-
2.5、創建模板
-
在resources下創建templates,并創建模板檔案freemarker.ftl檔案(模板中的插值運算式最侄訓被freemarker替換成具體的資料)
-
撰寫一個簡單的HTML模板
-
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Hello Freemarker!</title> </head> <body> <b>普通文本 String 展示:</b><br><br> Welcome to SuperCoolMan's home !! <br> I’m 99 years old this year !! <br> <hr> <hr> </body> </html>
-
2.6、創建測驗類并測驗
-
創建Controller類,添加資料,最后回傳模板檔案
-
測驗1:
-
package com.coolman.freemarker.controller; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.io.FileWriter; import java.io.IOException; import java.util.HashMap; @RestController @RequestMapping("/freemarker") public class FreemarkerController { // 引入freemarker.template包下的Configuration類,用來獲取指定的模板物件 @Autowired private Configuration configuration; /** * 通過模板檔案,生成html檔案 */ @GetMapping("/test") public String getHtml() { try { // 使用Configuration的getTemplate方法,指定模板檔案,獲取模板物件 Template template = configuration.getTemplate("HelloFreemarker.ftl"); // 系結資料 // 資料1: HashMap<String, Object> map = new HashMap<>(); map.put("name", "SuperCoolMan"); map.put("age", 99); FileWriter fileWriter = new FileWriter("E:\\系統默認\\桌面\\news-init\\freemarker-demo\\src\\main\\resources\\testHtml\\HelloFreemarker.html"); template.process(map, fileWriter); return "SUCCESS!"; } catch (IOException | TemplateException e) { e.printStackTrace(); } return "ERROR!"; } } -
瀏覽器打開生成的靜態檔案
-

-
-
-
修改Controller中的方法,添加Person物件資料
-
package com.coolman.freemarker.controller; import com.coolman.freemarker.model.Person; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.io.FileWriter; import java.io.IOException; import java.util.HashMap; @RestController @RequestMapping("/freemarker") public class FreemarkerController { // 引入freemarker.template包下的Configuration類,用來獲取指定的模板物件 @Autowired private Configuration configuration; /** * 通過模板檔案,生成html檔案 */ @GetMapping("/test") public String getHtml() { try { // 使用Configuration的getTemplate方法,指定模板檔案,獲取模板物件 Template template = configuration.getTemplate("HelloFreemarker.ftl"); // 系結資料 // 資料1: HashMap<String, Object> map = new HashMap<>(); map.put("name", "SuperCoolMan"); map.put("age", 99); // 資料2: map.put("person", new Person("超級猛男", 18)); FileWriter fileWriter = new FileWriter("E:\\系統默認\\桌面\\news-init\\freemarker-demo\\src\\main\\resources\\testHtml\\HelloFreemarker.html"); template.process(map, fileWriter); return "SUCCESS!"; } catch (IOException | TemplateException e) { e.printStackTrace(); } return "ERROR!"; } } -
修改模板
-
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Hello Freemarker!</title> </head> <body> <b>普通文本 String 展示:</b><br><br> Welcome to ${name}'s home !! <br> I’m ${age} years old this year !! <br> <hr> <b>物件Person中的資料展示:</b><br/> 姓名:${person.name}<br/> 年齡:${person.age} <hr> </body> </html>
-
-
瀏覽器打開生成的靜態檔案
-

-
2.7、總結
三、freemarker語法指令
3.1、基礎語法
3.1.1、注釋
-
注釋,即
<#-- -->,介于其之間的內容會被freemarker忽略-
<#-- 我是一個freemarker的注釋-->
-
3.1.2、插值
-
插值(Interpolation):即
${...}部分,freemarker會用真實的值代替${}(PS:如果回傳的資料中沒有該真實值,freemarker服務會直接報錯)-
Welcome to ${name}'s home
-
3.1.3、FTL指令
-
FTL指令:和HTML標記類似,名字前加
#予以區分,Freemarker會決議標簽中的運算式或邏輯-
<# > FTL指令 </#>
-
3.1.4、文本
-
文本,僅文本資訊,這些不是freemarker的注釋、插值、FTL指令的內容會被freemarker忽略決議,直接輸出內容
-
<#--freemarker中的普通文本--> 我是一個普通的文本
-
3.2、集合指令(List、Map)
接下來的測驗,只截取部分代碼,直接在原代碼的基礎上增加即可
-
為了Controller盡可能簡略,創建一個
getData方法,回傳一個Map集合,Controller方法直接呼叫這個getData生成測驗資料即可-
private Map<String, Object> getData() { HashMap<String, Object> map = new HashMap<>(); // String型別: map.put("name", "SuperCoolMan"); map.put("age", 99); // Person型別: map.put("person", new Person("超級猛男", 18)); // return map; }
-
3.2.1、List集合
-
Controller
-
// List集合型別 ArrayList<Person> list = new ArrayList<>(); list.add(new Person("瞳夕", 18)); list.add(new Person("二呆", 18)); list.add(new Person("嘿嘿", 18)); map.put("wifeList", list);
-
-
模板
-
<b>List型別中的資料展示:</b><br/> <#list wifeList as wife> 序號:${wife_index + 1} <br/> <#--freemarker中FTL指令自帶的序號屬性,默認從0開始--> 姓名:${wife.name} <br/> 年齡:${wife.age} <br/><br/> </#list> <hr>
-
-
最終效果
3.2.2、Map集合
-
Controller
-
// Map集合型別 HashMap<String, Object> anOtherMap = new HashMap<>(); anOtherMap.put("smallWife1", new Person("莫妮卡", 18)); anOtherMap.put("smallWife2", new Person("瑪麗蓮夢露", 18)); map.put("smallWife", anOtherMap);
-
-
模板
-
<b>Map + Person 型別中的資料展示:</b><br/> <b>方式一:通過map['keyname'].property 輸出對應資訊:</b><br/> 性別:${wifeMap['smallWife1'].name} <br/> 年齡:${wifeMap['smallWife1'].age} <br/> <b>方式二:通過map.keyname.property 輸出對應資訊:</b><br/> 性別:${wifeMap.smallWife2.name} <br/> 年齡:${wifeMap.smallWife2.age} <br/> <hr>
-
-
最終效果
-
遍歷Map集合
-
模板
-
<b>遍歷Map中多個Person資訊:</b><br/> <#list wifeMap?keys as key> 序號:${key_index} <br/> 性別:${key.name} <br/> 年齡:${key.age} <br/><br/> </#list> <hr>
-
-
最終效果
-
3.3、if指令
-
if指令即判斷指令,是常用的FTL指令,freemarker在決議的時候遇到if會進行判斷,條件為真則輸出if中間的內容,否則跳過內容不在輸出-
指令格式
-
<#if >...</#if>
-
-
-
Controller
-
// if test map.put("score", 88);
-
-
模板
-
<b>if指令測驗:</b><br/> <#if (score > 90)> 繼續努力 <#elseif (score > 80)> 面包總會有的 <#else> 革命尚未成功,同志仍需努力 </#if> <hr>
-
-
最終效果
3.4、空值處理
3.4.1、判斷某變數是否存在
-
語法格式
variable??
-
如果該變數存在,回傳true,否則回傳false
-
如下例所示
-
<#if stus??> <#list stus as stu> ...... </#list> </#if>
-
3.4.2、缺失變數默認值
- 使用
!要指定一個默認值,當變數為空的時候顯示默認值- 例:
${name!'默認值'}表示如果name為空,顯示默認值
- 例:
- 如果是嵌套物件則建議使用
()括起來- 例:
${(stu.bestFriend.name)!"默認值"}表示如果stu或者bestFriend或者name為空默認顯示默認值
- 例:
3.5、內建函式
3.5.1、獲取集合大小
- 模板中直接取值
${集合名?size}
3.5.2、日期格式化
- 后端回傳一個Date物件,模板要取值,則如下所示
map.put("today",new Date())- 顯示年月日
${today?date}
- 顯示時分秒
${today?time}
- 顯示日期+時間
${today?datetime}
- 自定義格式化
${today?string("yyyy年MM月")}
3.5.3、內建函式c(數字格式化)
- 后端回傳一串數字,模板可以對其進行格式化,如下所示
map.put("point", 102920122);
- point是數字型,使用
${point}會顯示這個數字的值,每三位使用逗號隔開 - 如果不像顯示為每三位分隔的數字,可以使用
c函式將數字轉成字串輸出 - 指令格式如下所示
${point?c}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/500397.html
標籤:其他
上一篇:C++函式模板和類模板





