FreeMarker 快速入门
FreeMarker 快速入門
FreeMarker是一個很值得去學習的模版引擎。它是基于模板文件生成其他文本的通用工具。本章內(nèi)容通過如何使用FreeMarker生成Html web 頁面 和 代碼自動生成工具來快速了解FreeMarker。
1 簡介
FreeMarker是一款用java語言編寫的模版引擎,它雖然不是web應用框架,但它很合適作為web應用框架的一個組件。
特點:
工作原理:(借用網(wǎng)上的圖片)
2 FreeMarker 程序
這里通過模擬簡單的代碼自動生產(chǎn)工具來感受第一個FreeMarker程序。
項目目錄結(jié)構(gòu)
項目創(chuàng)建流程
第一步:創(chuàng)建一個maven項目導入 FreeMarker jar 包
第二步:創(chuàng)建目錄templates,并創(chuàng)建一個 FreeMarker模版文件 hello.ftl
第三步:創(chuàng)建一個運行FreeMarker模版引擎的 FreeMarkerDemo.java 文件
第四步:運行main方法后刷新項目
pom.xml 文件 ,maven 項目核心文件,管理 jar 包。
<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.freemark</groupId><artifactId>freemarkerStudy</artifactId><version>0.0.1-SNAPSHOT</version><packaging>war</packaging><dependencies><dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.20</version></dependency></dependencies></project>hello.ftl FreeMarker基本語法:?xxxxxx相當于占位符,java后臺給xxx賦值后,再通過{}輸出
package ${classPath};public class ${className} {public static void main(String[] args) {System.out.println("${helloWorld}");}}FreeMarkerDemo.java 核心方法,使用 FreeMarker 模版引擎。
package com.freemark.hello;import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.HashMap; import java.util.Map;import freemarker.template.Configuration; import freemarker.template.Template;/*** 最常見的問題: * java.io.FileNotFoundException: xxx does not exist. 解決方法:要有耐心* FreeMarker jar 最新的版本(2.3.23)提示 Configuration 方法被棄用* 代碼自動生產(chǎn)基本原理:* 數(shù)據(jù)填充 freeMarker 占位符*/ public class FreemarkerDemo {private static final String TEMPLATE_PATH = "src/main/java/com/freemark/hello/templates";private static final String CLASS_PATH = "src/main/java/com/freemark/hello";public static void main(String[] args) {// step1 創(chuàng)建freeMarker配置實例Configuration configuration = new Configuration();Writer out = null;try {// step2 獲取模版路徑configuration.setDirectoryForTemplateLoading(new File(TEMPLATE_PATH));// step3 創(chuàng)建數(shù)據(jù)模型Map<String, Object> dataMap = new HashMap<String, Object>();dataMap.put("classPath", "com.freemark.hello");dataMap.put("className", "AutoCodeDemo");dataMap.put("helloWorld", "通過簡單的 <代碼自動生產(chǎn)程序> 演示 FreeMarker的HelloWorld!");// step4 加載模版文件Template template = configuration.getTemplate("hello.ftl");// step5 生成數(shù)據(jù)File docFile = new File(CLASS_PATH + "\\" + "AutoCodeDemo.java");out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(docFile)));// step6 輸出文件template.process(dataMap, out);System.out.println("^^^^^^^^^^^^^^^^^^^^^^^^AutoCodeDemo.java 文件創(chuàng)建成功 !");} catch (Exception e) {e.printStackTrace();} finally {try {if (null != out) {out.flush();}} catch (Exception e2) {e2.printStackTrace();}}}}運行程序后刷新項目,會發(fā)現(xiàn)多了一個AutoCodeDemo.java類。不僅僅是java類,xml也是可以。筆者就是通過FreeMarker做了一個簡易的工具類,公司的一個標準管理頁面及其增刪改查等功能,以及相關(guān)的配置文件(十三個文件),一個回車就全部自動生成(偷懶ing)。
3 FreeMarker 語法
語法和java很類似,其中宏的概念可能比較陌生,先上代碼
stringFreeMarker.ftl FreeMarker主要核心知識點
字符串輸出: ${"Hello ${name} !"} / ${"Hello " + name + " !"} <#assign cname=r"特殊字符完成輸出(http:\www.baidu.com)"> ${cname}字符串截取 : 通過下標直接獲取下標對應的字母: ${name[2]} 起點下標..結(jié)尾下標截取字符串:${name[0..5]}算數(shù)運算: <#-- 支持"+"、"-"、"*"、"/"、"%"運算符 --> <#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>內(nèi)建函數(shù): <#assign data = "abcd1234"> 第一個字母大寫:${data?cap_first} 所有字母小寫:${data?lower_case} 所有字母大寫:${data?upper_case} <#assign floatData = 12.34> 數(shù)值取整數(shù):${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> 定義無參數(shù)的宏macro--${name} </#macro> 使用宏macro: <@mo /> <#macro moArgs a b c> 定義帶參數(shù)的宏macro-- ${a+b+c} </#macro> 使用帶參數(shù)的宏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 核心方法
package com.freemark.demo;import java.util.List; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.Date; import java.util.ArrayList; import java.util.HashMap; import java.util.Map;import freemarker.template.Configuration; import freemarker.template.Template;public class FreeMarkerDemo {private static final String TEMPLATE_PATH = "src/main/java/com/freemark/demo/templates";public static void main(String[] args) {// step1 創(chuàng)建freeMarker配置實例Configuration configuration = new Configuration();Writer out = null;try {// step2 獲取模版路徑configuration.setDirectoryForTemplateLoading(new File(TEMPLATE_PATH));// step3 創(chuàng)建數(shù)據(jù)模型Map<String, Object> dataMap = new HashMap<String, Object>();dataMap.put("name", "itdragon博客");dataMap.put("dateTime", new Date());List<User> users = new ArrayList<User>();users.add(new User(1, "ITDragon 博客"));users.add(new User(2, "歡迎"));users.add(new User(3, "You!"));dataMap.put("users", users);// step4 加載模版文件Template template = configuration.getTemplate("stringFreeMarker.ftl");// step5 生成數(shù)據(jù)out = new OutputStreamWriter(System.out);// step6 輸出文件template.process(dataMap, out);} catch (Exception e) {e.printStackTrace();} finally {try {if (null != out) {out.flush();}} catch (Exception e2) {e2.printStackTrace();}}}}User.java 為了測試 FreeMarker的集合對象
package com.freemark.demo;public class User {private Integer id;private String name;public User() {}public User(Integer id, String name) {this.id = id;this.name = name;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "User [id=" + id + ", name=" + name + "]";}}最后的打印結(jié)果
字符串輸出: Hello itdragon博客 ! / Hello itdragon博客 ! 特殊字符完成輸出(http:\www.baidu.com)字符串截取 : 通過下標直接獲取下標對應的字母: d 起點下標..結(jié)尾下標截取字符串:itdrag算數(shù)運算: "+" : 15 "-" : 5 "*" : 50 "/" : 2 "%" : 0比較運算符: "*" : 50內(nèi)建函數(shù): 第一個字母大寫:Abcd1234 所有字母小寫:abcd1234 所有字母大寫:ABCD1234 數(shù)值取整數(shù):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,000List集合: ITDragon blog is cool include指令: 其他FreeMarker文件macro宏指令: 使用宏macro: 定義無參數(shù)的宏macro--itdragon博客 使用帶參數(shù)的宏macro: 定義帶參數(shù)的宏macro-- 6命名空間: 另外一個FreeMarker的變量 result : 30 另外一個FreeMarker的變量 修改otherFreeMarker.ftl中的otherName變量值語法詳解
數(shù)據(jù)類型
和java不同,FreeMarker不需要定義變量的類型,直接賦值即可。
字符串: value = "xxxx" 。如果有特殊字符 string = r"xxxx" 。單引號和雙引號是一樣的。
數(shù)值:value = 1.2。數(shù)值可以直接等于,但是不能用科學計數(shù)法。
布爾值:true or 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結(jié)束。一共是三個數(shù)。
比較運算符
== (等于),!= (不等于),gt(大于),gte(大于或者等于),lt(小于),lte(小于或者等于)。不建議用 >,< 可能會報錯!
一般和 if 配合使用
內(nèi)建函數(shù)
FreeMarker 提供了一些內(nèi)建函數(shù)來轉(zhuǎn)換輸出,其結(jié)構(gòu):變量?內(nèi)建函數(shù),這樣就可以通過內(nèi)建函數(shù)來轉(zhuǎn)換輸出變量。
html: 對字符串進行HTML編碼;
cap_first: 使字符串第一個字母大寫;
lower_case: 將字符串轉(zhuǎn)成小寫;
upper_case: 將字符串轉(zhuǎn)成大寫;
size: 獲得集合中元素的個數(shù);
int: 取得數(shù)字的整數(shù)部分。
變量空判斷
! 指定缺失變量的默認值;一般配置變量輸出使用
?? 判斷變量是否存在。一般配合if使用 <#if value??></#if>
宏指令
可以理解為java的封裝方法,供其他地方使用。宏指令也稱為自定義指令,macro指令
語法很簡單:<#macro val > 聲明macro </#macro>; 使用macro <@val />
命名空間
可以理解為java的import語句,為避免變量重復。一個重要的規(guī)則就是:路徑不應該包含大寫字母,使用下劃線_分隔詞語,myName --> my_name
語法很簡單:<#import "xxx.ftl" as val>
其他沒有說明的語法是因為和java一樣,沒什么特別之處。所以沒有列出來。
4 Freemarker Web
這里是和SpringMVC整合的,SpringMVC的配置就不多說了,筆者也寫過相關(guān)的文章,同時也會提供源碼
導入相關(guān)的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的前面,優(yōu)先找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/sp...
5 小結(jié)
1 知道了FreeMarker是一塊模版引擎,可以生產(chǎn)xml,html,java等文件
2 知道了FreeMarker文件提供占位符,java文件提供數(shù)據(jù),通過FreeMarker模版引擎生產(chǎn)有數(shù)據(jù)的頁面,文中是將數(shù)據(jù)放在Map中。web應用可以用setter/getter 方法
3 知道了FreeMarker語法中字符串的顯示特殊字符,截取的操作。以及一些內(nèi)置方法的使用
4 重點了解FreeMarker的空判斷知識點。判斷變量是否為空用 "??" ,如果變量為空設置默認值。如果不注意空問題,可能會出現(xiàn)黃色頁面的提示哦!
5 FreeMarker的宏概念,命名空間,引入文件,給變量賦值,集合的遍歷等。
6 Freemarker 整合SpringMVC。
from:https://segmentfault.com/a/1190000011768799
總結(jié)
以上是生活随笔為你收集整理的FreeMarker 快速入门的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Apache Camel简介与入门
- 下一篇: 全面探索 FreeMarker 模版引擎