freemarker是一個用java開發的模版引擎,百度百科:html
經常使用的java模版還有快要被拋棄的Jsp(熟悉)、Thymeleaf(瞭解)、Velocity(不知)java
freemarker不關心數據的來源,知識根據模版的內容,將數據模型在模版中顯示並輸出文件;web
SpringMVC在默認狀況下是支持freemarker視圖格式的,咱們建立SpringBoot項目直接上Demospring
pom.xml文件以下apache
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
日誌安排:lomback-spring.xml緩存
<?xml version="1.0" encoding="UTF-8"?> <configuration> <!--定義日誌文件的存儲地址,使用絕對路徑--> <property name="LOG_HOME" value="E:\logs"/> <!-- Console 輸出設置 --> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <!--格式化輸出:%d表示日期,%thread表示線程名,%-5level:級別從左顯示5個字符寬度%msg:日誌消息,%n是換行符--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> <charset>utf8</charset> </encoder> </appender> <!-- 按照天天生成日誌文件 --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!--日誌文件輸出的文件名--> <fileNamePattern>${LOG_HOME}/xc.%d{yyyy-MM-dd}.log</fileNamePattern> </rollingPolicy> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <!-- 異步輸出 --> <appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender"> <!-- 不丟失日誌.默認的,若是隊列的80%已滿,則會丟棄TRACT、DEBUG、INFO級別的日誌 --> <discardingThreshold>0</discardingThreshold> <!-- 更改默認的隊列的深度,該值會影響性能.默認值爲256 --> <queueSize>512</queueSize> <!-- 添加附加的appender,最多隻能添加一個 --> <appender-ref ref="FILE"/> </appender> <logger name="org.apache.ibatis.cache.decorators.LoggingCache" level="DEBUG" additivity="false"> <appender-ref ref="CONSOLE"/> </logger> <logger name="org.springframework.boot" level="DEBUG"/> <root level="info"> <!--<appender-ref ref="ASYNC"/>--> <appender-ref ref="FILE"/> <appender-ref ref="CONSOLE"/> </root> </configuration>
配置文件:application.ymlapp
server: port: 8888 spring: application: name: test-freemarker freemarker: cache: false #關閉模版緩存 settings: template_update_delay: 0 #檢查模版更新延遲時間,0表示當即檢查,若是大於0會有延遲,不利於測試唷 logging.level.org.springframework.boot.autoconfigure: ERROR #後來加上的,專治SpringBoot項目起來不少日誌的狀況
咱們建立一個模型類,用於測試:待用異步
@Data @ToString public class People { private String username; private int age; private Float money; private List<People> friends; //他的朋友們 private People bestPeople; //他最好的朋友 }
建立模版:函數
在resource目錄下建立templates目錄,用來存放freemarker的模版,默認該目錄spring-boot
在templates中建立 test1.ftl內容以下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>FreemarkerTest1</title> </head> <body> 歡迎您:${name} ! </body> </html>
編寫Controller:
@Controller @RequestMapping("/freemarker") public class FreemarkerController { //待用 @Autowired private RestTemplate restTemplate; @RequestMapping("/test") public String freemarker(Map<String,Object> map){ map.put("name", "警察叔叔"); return "test1"; } }
編寫啓動類:
@SpringBootApplication public class FreemarkerApplication { public static void main(String[] args) { SpringApplication.run(FreemarkerApplication.class); } //待用 @Bean public RestTemplate instance(){ return new RestTemplate(new OkHttp3ClientHttpRequestFactory()); } }
等項目起來了,咱們能夠訪問測試:http://localhost:8888/freemarker/test
有沒有一種Jsp的味道在裏面?反正我感受是查詢的意思,後面的語法有些改變
Freemarker靜態化依賴與數據模型和模版,下面定義數據模型
在上面的那個小Demo中,咱們的數據模型也有使用,至於形參Map即爲Freemarker靜態化所須要的數據模型,在Map中填充數據便可
@Controller @RequestMapping("/freemarker") public class FreemarkerController { @Autowired private RestTemplate restTemplate; @RequestMapping("/test") public String freemarker(Map<String,Object> map){ map.put("name", "警察叔叔"); //三我的的信息 People p1 = new People("Ninja400",10,12580.01f,null,null); People p2 = new People("Ninja650",20,12580.01f,null,null); People p3 = new People("Ninja250",30,12580.01f,null,null); //p1有兩個好友 分別是p2 p3 List<People> friends = new ArrayList<>(); friends.add(p2); friends.add(p3); p1.setFriends(friends); //向Map中放入個人朋友們List map.put("friends", friends); //三我的的信息採集 HashMap<String,People> peopleMap = new HashMap<>(); peopleMap.put("p1", p1); peopleMap.put("p2", p2); peopleMap.put("p3", p3); //所有People的信息和 個人信息 map.put("peopleMap",peopleMap); map.put("p1", p1); return "test1"; } }
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>FreemarkerTest1</title> </head> <body> 歡迎您:${name}!下面是個人同夥們! <table> <tr> <td>序號</td> <td>姓名</td> <td>年齡</td> <td>錢包</td> </tr> <#list friends as friend> <tr> <td>${friend_index + 1}</td> <td>${friend.username}</td> <td>${friend.age}</td> <td>${friend.money}</td> </tr> </#list> </table> </body> </html>
<#list friends as friend> 使用list指令遍歷friends集合並將得到的每一個值賦值給friend
_index:獲得循環的下標,從0開始
輸出p1的信息<br/> 姓名:${p1.username}<br/> 年齡:${p1.age}<br/> 遍歷輸出p一、p二、p3的信息<br/> <table> <tr> <td>序號</td> <td>姓名</td> <td>年齡</td> <td>錢包</td> </tr> <#list peopleMap?keys as k> <tr> <td>${k_index + 1}</td> <td>${peopleMap[k].username}</td> <td>${peopleMap[k].age}</td> <td >${peopleMap[k].money}</td> </tr> </#list> </table>
${p1.username} :若是參數是在咱們的形參中,當存如後可經過Map的主鍵這樣獲取
<#list peopleMap?keys as k> 遍歷這個Map,指定主鍵用K表示
<table>
<tr>
<td>序號</td>
<td>姓名</td>
<td>年齡</td>
<td>錢包</td>
</tr>
<#list friends as friend>
<tr>
<td>${friend_index + 1}</td>
<td <#if friend.username == 'Ninja250'> style="background: dodgerblue" </#if>>${friend.username}</td>
<td>${friend.age}</td>
<td>${friend.money}</td>
</tr>
</#list>
</table>
<td <#if friend.username == 'Ninja250'> style="background: dodgerblue" </#if>>${friend.username}</td>
若是遍歷獲得的對象的username屬性是 Ninja250,該行的背景色顯示爲藍色
FreeMarker支持的算術運算符包括:+、 - 、 * 、 / 、 % 2
邏輯運算符有以下幾個: 邏輯與:&& 邏輯或:|| 邏輯非:! 邏輯運算符只能做用於布爾值,不然將產生錯誤
比較運算符 表達式中支持的比較運算符有以下幾個:
1 =或者==:判斷兩個值是否相等.
2 !=:判斷兩個值是否不等.
3 >或者gt:判斷左邊值是否大於右邊值
4 >=或者gte:判斷左邊值是否大於等於右邊值
5 <或者lt:判斷左邊值是否小於右邊值
6 <=或者lte:判斷左邊值是否小於等於右邊值
注意:
=和!=能夠用於字符串,數值和日期來比較是否相等,但=和!=兩邊必須是相同類型的值,不然會產生錯誤,並且 FreeMarker是精確比較,"x","x ","X"是不等的.其它的運行符能夠做用於數字和日期,但不能做用於字符串,大部分的時候,使用gt等字母運算符代替>會有更好的效果,由於 FreeMarker會把>解釋成FTL標籤的結束字符,固然,也可使用括號來避免這種狀況,如:<#if (x>y)>
判斷某變量是否存在使用: xx??,以下,
<#if friends??>:爲了防止friends爲空報錯能夠加一個預判斷,返回boolean
<#if friends??>
<#list friends as friend>
<tr>
<td>${friend_index + 1}</td>
<td <#if friend.username == 'Ninja250'> style="background: dodgerblue" </#if>>${friend.username}</td>
<td>${friend.age!""}</td>
<td>${friend.money}</td>
</tr>
</#list>
</#if>
<td>${friend.age!""}</td> :當這個對象的age屬性爲空時,使用缺失變量默認爲空字符串 「」
使用!必定要指定一個默認值,當咱們的屬性存在多層嵌套時,能夠用括號括起來,好比:
${(p1.bestPeople.name)!''} :若是p1最好的朋友的name這個屬性爲空,用空字符串表示
內建函數語法格式:變量 + ? + 函數名稱
某個集合的大小:
我有${friends?size}個同夥!
日期格式化:
map.put("now", new Date());
顯示年月日: ${now?date} <td/> 顯示時分秒:${now?time} <td/> 顯示日期+時間:${now?datetime} <td/> 自定義格式化: ${now?string("yyyy年MM月")}
內建函數
map.put("point",123456789);
當point是數字型,使用${point}會顯示這個數字的值,默認每隔三位使用逗號分隔。 若是不想顯示爲每三位分隔的數字,可使用c函數將數字型轉成字符串輸出
咱們的座機號碼是:<br> ${point} <br> ${point?c} <br>
將Json字符串撰文對象
<#assign text="{'name':'挽起袖子的年輕人','address':'四川省成都市成華區動物園單身狗圈養處'}" /> <#assign data=text?eval /> 我是誰:${data.name} 地址:${data.address}