1.集成
1.1添加jar包
在web/pom.xml中添加jar包。
<!--freemark -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>
<!--more-->
1.2在mvc-dispatcher.xml中添加视频解析器
<bean id="freemarkConfig"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="classpath:messages/freemark.properties" />
</bean>
<bean id="fmXmlEscape" class="freemarker.template.utility.XmlEscape" />
<!-- 配置FreeMark视图 -->
<bean id="freeMarkerViewResolver"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="contentType" value="text/html;charset=UTF-8" />
<property name="viewClass"
value="org.springframework.web.servlet.view.freemarker.FreeMarkerView" />
<property name="suffix" value=".ftl" />
<property name="cache" value="true" />
<property name="exposeSessionAttributes" value="true" />
<property name="exposeRequestAttributes" value="true" />
<property name="exposeSpringMacroHelpers" value="true" />
<!-- 在页面中使用${rc.contextPath}就可获得contextPath -->
<property name="requestContextAttribute" value="rc" />
<property name="order" value="0" />
</bean>
<bean id="FreeMarkerConfigurer"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/WEB-INF/ftl/" />
<property name="defaultEncoding" value="UTF-8" />
<property name="freemarkerSettings" ref="freemarkConfig" />
<property name="freemarkerVariables">
<map>
<entry key="xml_escape" value-ref="fmXmlEscape" />
</map>
</property>
</bean>
在messages下添加messages/freemark.properties
tag_syntax=auto_detect
template_update_delay=30
default_encoding=UTF-8
output_encoding=UTF-8
locale=zh_CN
date_format=yyyy-MM-dd
time_format=HH:mm:ss
datetime_format=yyyy-MM-dd HH:mm:ss
number_format=0.######
whitespace_stripping=true
url_escaping_charset=UTF-8
添加jsp视图解析器order属性。
<!-- Freemark找不到找jsp -->
<property name="order" value="1" />
简单测试略。默认先找freemark解析,找不到找jsp。返回json与他们无关。
2.freemark
2.1 简单介绍
Apache FreeMarker is a template engine: a Java library to generate text output (HTML web pages, e-mails, configuration files, source code, etc.) based on templates and changing data.
<center> ![](http://freemarker.org/images/overview.png) </center> Template + data-model = output
2.2 data-model
和程序开发数据类型基本一致。
- 树状基本结构,树可以复杂而且有很大的深度。
- 字符串,数字,日期/时间,布尔值。
- 哈希表,Map:${product.proPic.price}
- 序列器,如Java数组、List。变量通过数字索引来检索,索引通常从零开始。${products[0].name}
2.2.1日期的处理:
java.sql.date会自动转换 java.util.date: ${(date?string("yyyy-MM-dd HH:mm"))!}
FreeMarker中的日期时间处理 Built-ins for date/time/date-time values
2.2.2 空值处理
# Welcome ${user!"visitor"}!
<#--user为空,显示"visitor"-->
<#if user??>
# Welcome ${user}!
</#if>
<#-- ?? 判断用户是否为空-->
2.3 Templates
2.3.1 List
- list的长度 ${books?size}
- 集合迭代
<#list studentsList as student>
# id:${student.id}
# name:${student.name}
</#list>
如果studentsList没有元素,那么依旧会有如下输出 id:
name:
所以为了避免这一问题。可以使用如下的表示: 注意:在2.3.23后才支持官方网站更新日志
<#list studentsList>
<#items as student>
# id:${student.id}
# name:${student.name}
</#items>
</#list>
如果集合元素为空,那么还可以使用<#else>来进行为空时的操作,这时就会去do something,例如:
<#list studentsList>
<#items as student>
# id:${student.id}
# name:${student.name}
</#items>
<#else>
Do Something…
</#list>
可以使用<#sep>something</#sep>来分割输出的内容。例如:
Fruits: <#list misc.fruits as fruit>${fruit}<#sep>, </#list>
那么就会将输出的水果用逗号分开,like <p>Fruits: orange, banana
对于集合而言他有下面的属性: 集合本身有以下属性: index:索引,从0开始 counter:计数,从1开始 item_parity:奇偶性,返回当前counter的奇偶性,返回字符串"odd","even", 可以这样使用
<td class="${animal?item_parity}Row">
一个简洁的例子
<#list books>
<#items as book>
<li class="abook clearFix">![](${book.img})
<div class="book-text">
<p class="book-title text-min">
${book.title}--index:${book_index} </br>
${book?counter}
${book?index}
${book?item_parity}
[开始阅读](${book.url})
</div>
</li>
</#items>
</#list>
2.3.2控制语句
- if..else 判断
<#if expression>
<#elseif expression >
<#else>
</#if>
list和if可以嵌套使用。遍历的时候判断。
2.3.3引用<#include url>
使用这个标签,可以引入外部的另一段内容到当前的文件中。
2.3.4 一些内建函数
函数调用使用?,如: animal?item_parity
- html:对字符串进行HTML编码
- cap_first:使字符串第一个字母大写
- lower_case:将字符串转换成小写
- upper_case:将字符串转换成大写
- trim:去掉字符串前后的空白字符
- size:获得序列中元素的数目
- int:取得数字的整数部分(如-1.9?int的结果是-1) 具体的可以看这
2.3.5 宏 自定义标签
macro, nested, return
<#macro name param1 param2 ... paramN>
...
<#nested loopvar1, loopvar2, ..., loopvarN>
...
<#return>
...
</#macro>
参数说明:
name: 宏的名字,调用时使用<@name> param1 param2: 传递进去的参数 nested: macro 开始和结束标签之间的内容。 return: 就是返回了,后边的不输出。
简单例子, 参数含有默认值。
<#macro test foo bar="Bar" baaz=-1>
Test text, and the params: ${foo}, ${bar}, ${baaz}
</#macro>
<@test foo="a" bar="b" baaz=5*5-2/>
<@test foo="a" bar="b"/>
<@test foo="a" baaz=5*5-2/>
<@test foo="a"/>
output:
Test text, and the params: a, b, 23
Test text, and the params: a, b, -1
Test text, and the params: a, Bar, 23
Test text, and the params: a, Bar, -1
人人通首页DEMO: template.ftl
<#macro htmlHead title charset="utf-8" lang="zh-CN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=${charset}" />
<meta http-equiv="Content-Language" content="${lang}"/>
<title>${title}</title>
<#nested>
</head>
</#macro>
<#macro htmlBody>
<body class="all-bj">
<#nested>
</body>
</html>
</#macro>
调用页面
<#include "templet.ftl"/>
<@htmlHead title="人人通 ">
<link rel="stylesheet" href="${rc.contextPath}/static/css/comm.css">
</@htmlHead>
<@htmlBody>
<#include "./header.ftl"/>
<div class="wrap content">
<#include "./body-hearder.ftl">
<div id="work" class="content-body clearFix">
<div class="content-left clearFix">
<#include "prefile.ftl">
<#include "app.ftl">
<#include "books.ftl">
</div>
<#include "right.ftl">
</div>
</div>
<#import "footer.ftl" as footer />
<@footer.copyright date="2009-2016"/>
</@htmlBody>
2.3.6 命名空间
就是assign 和 macro 指令创建的变量的集合。
- 变量:
-
''简单''变量: 它能从模板中的任何位置来访问,或者从使用 include 指令引入的模板访问。可以使用 assign 指令来创建或替换这些变量。因为宏和方法只是变量,那么 macro 指令 和 function 指令 也可以用来设置变量,就像 assign 那样。
-
局部变量:它们只能被设置在 宏定义体内, 而且只在宏内可见。一个局部变量的生命周期只是宏的调用过程。可以使用 local指令 在宏定义体内创建或替换局部变量。
-
循环变量:循环变量是由如 list 指令自动创建的,而且它们只在指令的开始和结束标记内有效。宏 的参数是局部变量而不是循环变量。
-
全局变量:这是一个高级话题了, 并且这种变量最好别用。即便它们属于不同的命名空间, 全局变量也被所有模板共享,因为它们是被 import进来的, 不同于 include 进来的。那么它们的可见度就像数据模型那样。 全局变量通过 global指令来定义。
-
命名空间例子:
<#macro copyright date>
Copyright (C) ${date} Julia Smith. All rights reserved.
</#macro>
<#assign mail = "jsmith@acme.com">
注意: import 导入命名空间,不是include。不同的命名空间变量名可以相同。
<#import "/lib/my_test.ftl" as my> <#-- the hash called "my" will be the "gate" -->
<@my.copyright date="1999-2002"/>
${my.mail}
output:
Copyright (C) 1999-2002 Julia Smith. All rights reserved.
jsmith@acme.com
声明相同的变量
<#import "/lib/my_test.ftl" as my>
<#assign mail="fred@acme.com">
<@my.copyright date="1999-2002"/>
${my.mail}
${mail}
output:
Copyright (C) 1999-2002 Julia Smith. All rights reserved.
Email: jsmith@acme.com
jsmith@acme.com
fred@acme.com
如果想改掉命名空间内的变量该怎么办呢?
<#import "/lib/my_test.ftl" as my>
${my.mail}
<#assign mail="jsmith@other.com" in my>
${my.mail}
命名空间就和java中的类一样,宏是类中的静态方法。