Thymeleaf模板引擎简介
Thymeleaf是网站或者独立应用程序的新式的服务端java模板引擎,可以执行HTML,XML,
JavaScript,CSS甚至纯文本模板。
Thymeleaf的主要目标是提供一个以优雅的高可维护型的方式创建模板,为了达到这个目的,他建立了
自然模板的概念,以一种不影响模板设计原型的方式将逻辑注入到模板文件中,可以显著的减少设计和
开发之间的沟通成本。
用Thymeleaf编写的HTML模板在外观和功能上仍然类似于HTML,从而使应用程序中运行的实际模板可
以用作有用的设计工件。示例代码如下:
<table>
<thead>
<tr>
<th th:text="#{msgs.headers.name}">Name</th>
<th th:text="#{msgs.headers.price}">Price</th>
</tr>
</thead>
<tbody>
<tr th:each="prod: ${allProducts}">
<td th:text="${prod.name}">Oranges</td>
<td th:text="${#numbers.formatDecimal(prod.price, 1, 2)}">0.99</td>
</tr>
</tbody>
</table>
在使用Thymeleaf渲染传统HTML页面时,整个Thymeleaf页面与HTML基本类似,需要先引入
Thymeleaf模板标签;然后使用Thymeleaf模板的相关标签动态填充页面内容。
1、Thymeleaf常用标签
在使用Thymeleaf时页面要引入名称空间: xmlns:th="http://www.thymeleaf.org"
关键字 | 功能介绍 | 案例 |
---|---|---|
th:id | 替换id | <input th:id="'xxx' + ${collect.id}"/> |
th:text | 文本替换 | <p th:text="${collect.description}">description</p> |
th:utext | 支持html的文本替换 | <p th:utext="${htmlcontent}">conten</p> |
th:object | 替换对象 | <div th:object="${session.user}"> |
th:value | 属性赋值 | <input th:value="${user.name}" /> |
th:with | 变量赋值运算 | <div th:with="isEven=${prodStat.count}%2==0"></div> |
th:style | 设置样式 | th:style="'display:' + @{(${sitrue} ? 'none' : 'inline-block')} + ''" |
th:onclick | 点击事件 | th:onclick="'getCollect()'" |
th:each | 遍历集合 | tr th:each="user,userStat:${users}"> |
th:if | 判断条件 | <a th:if="${userId == collect.userId}" > |
th:unless | 和th:if判断相反 | <a th:href="@{/login}" th:unless=${session.user != null}>Login</a> |
th:href | 链接地址 | <a th:href="@{/login}" th:unless=${session.user != null}>Login</a> /> |
th:switch | 多路选择 配合th:case 使用 | <div th:switch="${user.role}"> |
th:case | th:switch的一个分支 | <p th:case="'admin'">User is an administrator</p> |
th:fragment | 布局标签,定义一个代码片段,方便其它地方引用 | <div th:fragment="alert"> |
th:include | 布局标签,替换内容到引入的文件 | <head th:include="layout :: htmlhead" th:with="title='xx'"></head> /> |
th:replace | 布局标签,替换整个标签到引入的文件 | <div th:replace="fragments/header :: title"></div> |
th:selected | selected选择框 选中 | th:selected="(${xxx.id} == ${configObj.dd})" |
th:src | 图片类地址引入 | <img class="img-responsive" alt="App Logo" th:src="@{/img/logo.png}" /> |
th:inline | 定义js脚本可以使用变量 | <script type="text/javascript" th:inline="javascript"> |
th:action | 表单提交的地址 | <form action="subscribe.html" th:action="@{/subscribe}"> |
th:remove | 删除某个属性 | <tr th:remove="all"> 1.all:删除包含标签和所有的孩子。 |
th:attr | 设置标签属性,多个属性可以用逗号分隔 | 比如 th:attr="src=@{/image/aa.jpg},title=#{logo}" ,此标签不太优雅,一般用的比较少。 |
th:each
<tr th:each="collect,iterStat : ${collects}">
<th scope="row" th:text="${collect.id}">1</th>
<td ><img th:src="${collect.webLogo}"/></td>
<td th:text="${collect.url}">Mark</td><td th:text="${collect.title}">Otto</td>
<td th:text="${collect.description}">@mdo</td><td th:text="${terStat.index}">index</td>
</tr>
<!-- iterStat称作状态变量,属性有:
- index:当前迭代对象的index(从0开始计算)
- count: 当前迭代对象的index(从1开始计算)
- size:被迭代对象的大小
- current:当前迭代变量
- even/odd:布尔值,当前循环是否是偶数/奇数(从0开始计算)
- first:布尔值,当前循环是否是第一个
- last:布尔值,当前循环是否是最后一个 -->
2、标准表达式语法:
变量表达式即OGNL表达式或Spring EL表达式(在Spring术语中也叫model attributes)
${...} // 变量表达式,Variable Expressions
@{...} // 链接表达式,Link URL Expressions
#{...} // 消息表达式,Message Expressions
~{...} // 代码块表达式,Fragment Expressions
*{...} // 选择变量表达式,Selection Variable Expressions
表达式支持的语法
字面(Literals)
文本文字(Text literals): 'one text', 'Another one!',…
数字文本(Number literals): 0, 34, 3.0, 12.3,…
布尔文本(Boolean literals): true, false
空(Null literal): null
文字标记(Literal tokens): one, sometext, main,…
文本操作(Text operations)
字符串连接(String concatenation): +
文本替换(Literal substitutions): |The name is ${name}|
算术运算(Arithmetic operations)
二元运算符(Binary operators): +, -, *, /, %
减号(单目运算符)Minus sign (unary operator): -
布尔操作(Boolean operations)
二元运算符(Binary operators):and, or
布尔否定(一元运算符)Boolean negation (unary operator):!, not
比较和等价(Comparisons and equality)
比较(Comparators): >, <, >=, <= (gt, lt, ge, le)
等值运算符(Equality operators):==, != (eq, ne)
条件运算符(Conditional operators)
If-then: (if) ? (then)
If-then-else: (if) ? (then) : (else)
Default: (value) ?: (defaultvalue)
所有这些特征可以被组合并嵌套:
~{…} 代码块表达式
支持两种语法结构
推荐:~{templatename::fragmentname}
支持:~{templatename::#id}
-
templatename:模版名,Thymeleaf会根据模版名解析完整路径:/resources/templates/templatename.html,要注意文件的路径。
-
fragmentname:片段名,Thymeleaf通过th:fragment声明定义代码块,即:
th:fragment="fragmentname"
-
id:HTML的id选择器,使用时要在前面加上#号,不支持class选择器。
代码块表达式的使用
代码块表达式需要配合th属性(th:insert,th:replace,th:include)一起使用。
th:insert:将代码块片段整个插入到使用了th:insert的HTML标签中,
th:replace:将代码块片段整个替换使用了th:replace的HTML标签中,
th:include:将代码块片段包含的内容插入到使用了th:include的HTML标签中,
#{…} 消息表达式
消息表达式一般用于国际化的场景。
@{…} 链接表达式
不管是静态资源的引用,form表单的请求,凡是链接都可以用
@{...}
。这样可以动态获取项目路径,即便项目名变了,依然可以正常访问
#修改项目名,链接表达式会自动修改路径,避免资源文件找不到
server.context-path=/itdragon
链接表达式结构
无参:@{/xxx}
有参:@{/xxx(k1=v1,k2=v2)}
对应url结构:xxx?k1=v1&k2=v2
引入本地资源:@{/项目本地的资源路径}
引入外部资源:@{/webjars/资源在jar包中的路径}
列举:
<link th:href="@{/webjars/bootstrap/4.0.0/css/bootstrap.css}" rel="stylesheet">
<link th:href="@{/main/css/itdragon.css}" rel="stylesheet">
<form class="form-login" th:action="@{/user/login}" th:method="post" >
<a class="btn btn-sm" th:href="@{/login.html(l='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/login.html(l='en_US')}">English</a>
${…} 变量表达式
变量表达式功能
-
可以获取对象的属性和方法
-
可以使用ctx,vars,locale,request,response,session,servletContext内置对象
-
可以使用dates,numbers,strings,objects,arrays,lists,sets,maps等内置方法(重点介绍)
3、常用的内置对象
ctx :// 上下文对象。
vars :// 上下文变量。
locale:// 上下文的语言环境。
request:// (仅在web上下文)的 HttpServletRequest 对象。
response:// (仅在web上下文)的 HttpServletResponse 对象。
session:// (仅在web上下文)的 HttpSession 对象。
servletContext:// (仅在web上下文)的 ServletContext 对象
这里以常用的Session举例,用户刊登成功后,会把用户信息放在Session中,Thymeleaf通过内置对象将值从session中获取。
// java 代码将用户名放在session中
session.setAttribute("userinfo",username);
// Thymeleaf通过内置对象直接获取
th:text="${session.userinfo}"
4、常用的内置方法
strings:// 字符串格式化方法,常用的Java方法它都有。比如:equals,equalsIgnoreCase,length,trim,toUpperCase,toLowerCase,indexOf,substring,replace,startsWith,endsWith,contains,containsIgnoreCase等
numbers:// 数值格式化方法,常用的方法有:formatDecimal等
bools:// 布尔方法,常用的方法有:isTrue,isFalse等
arrays:// 数组方法,常用的方法有:toArray,length,isEmpty,contains,containsAll等
lists,// sets:集合方法,常用的方法有:toList,size,isEmpty,contains,containsAll,sort等
maps:// 对象方法,常用的方法有:size,isEmpty,containsKey,containsValue等
dates:// 日期方法,常用的方法有:format,year,month,hour,createNow等
<!DOCTYPE html><html lang="en" xmlns:th="http://www.thymeleaf.org"><head>
<meta charset="UTF-8">
<title>ITDragon Thymeleaf 内置方法</title></head><body>
<h2>ITDragon Thymeleaf 内置方法</h2>
<h3>#string类型方法 </h3>
<div th:if="${not #strings.isEmpty(itdragonStr)}" >
<p>Old Str : <span th:text="${itdragonStr}"/></p>
<p>toUpperCase : <span th:text="${#strings.toUpperCase(itdragonStr)}"/></p>
<p>toLowerCase : <span th:text="${#strings.toLowerCase(itdragonStr)}"/></p>
<p>equals : <span th:text="${#strings.equals(itdragonStr, 'itdragonblog')}"/></p>
<p>equalsIgnoreCase :
<span th:text="${#strings.equalsIgnoreCase(itdragonStr, 'itdragonblog')}"/></p>
<p>indexOf : <span th:text="${#strings.indexOf(itdragonStr, 'r')}"/></p>
<p>substring : <span th:text="${#strings.substring(itdragonStr, 2, 8)}"/></p>
<p>replace : <span th:text="${#strings.replace(itdragonStr, 'it', 'IT')}"/></p>
<p>startsWith : <span th:text="${#strings.startsWith(itdragonStr, 'it')}"/></p>
<p>contains : <span th:text="${#strings.contains(itdragonStr, 'IT')}"/></p>
</div>
<h3>#numbers数值型方法</h3>
<div>
<p>formatDecimal 整数部分随意,小数点后保留两位,四舍五入:
<span th:text="${#numbers.formatDecimal(itdragonNum, 0, 2)}"/></p>
<p>formatDecimal 整数部分保留五位数,小数点后保留两位,四舍五入:
<span th:text="${#numbers.formatDecimal(itdragonNum, 5, 2)}"/></p>
</div>
<h3>#bool类型方法</h3>
<div th:if="${#bools.isTrue(itdragonBool)}">
<p th:text="${itdragonBool}"></p>
</div>
<h3>#arrays数组方法 </h3>
<div th:if="${not #arrays.isEmpty(itdragonArray)}">
<p>length : <span th:text="${#arrays.length(itdragonArray)}"/></p>
<p>contains : <span th:text="${#arrays.contains(itdragonArray, 5)}"/></p>
<p>containsAll : <span th:text="${#arrays.containsAll(itdragonArray, itdragonArray)}"/></p>
</div>
<h3>#list集合类型方法 </h3>
<div th:if="${not #lists.isEmpty(itdragonList)}">
<p>size : <span th:text="${#lists.size(itdragonList)}"/></p>
<p>contains : <span th:text="${#lists.contains(itdragonList, 0)}"/></p>
<p>sort : <span th:text="${#lists.sort(itdragonList)}"/></p>
</div>
<h3>#map集合类型方法 </h3>
<div th:if="${not #maps.isEmpty(itdragonMap)}">
<p>size : <span th:text="${#maps.size(itdragonMap)}"/></p>
<p>containsKey : <span th:text="${#maps.containsKey(itdragonMap, 'thName')}"/></p>
<p>containsValue : <span th:text="${#maps.containsValue(itdragonMap, '#maps')}"/></p>
</div>
<h3>#date日期类型方法 </h3>
<div>
<p>format : <span th:text="${#dates.format(itdragonDate)}"/></p>
<p>custom format : <span th:text="${#dates.format(itdragonDate, 'yyyy-MM-dd HH:mm:ss')}"/></p>
<p>day : <span th:text="${#dates.day(itdragonDate)}"/></p>
<p>month : <span th:text="${#dates.month(itdragonDate)}"/></p>
<p>monthName : <span th:text="${#dates.monthName(itdragonDate)}"/></p>
<p>year : <span th:text="${#dates.year(itdragonDate)}"/></p>
<p>dayOfWeekName : <span th:text="${#dates.dayOfWeekName(itdragonDate)}"/></p>
<p>hour : <span th:text="${#dates.hour(itdragonDate)}"/></p>
<p>minute : <span th:text="${#dates.minute(itdragonDate)}"/></p>
<p>second : <span th:text="${#dates.second(itdragonDate)}"/></p>
<p>createNow : <span th:text="${#dates.createNow()}"/></p>
</div></body></html>
SpringBoot整合Thymeleaf模板
(1)导入依赖
<!-- Thymeleaf模板依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- Web模块开发依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
(2)编写项目配置文件
打开application.properties全局配置文件,在该文件中对Thymeleaf模板页面的相关配置进行设置:
# thymeleaf页面缓存设置(默认为true),开发中方便调试应设置为false,上线稳定后应保持默认true
spring.thymeleaf.cache=false
上述配置中,spring.thymeleaf.cache表示是否开启Thymeleaf模板缓存,默认为true,在开发过程中通
常会关闭缓存,保证项目调试过程中数据能够及时响应。
(3)创建Web控制类
在项目中创建名为com.hopu.controller的包,并在该包下创建一个用于前端模板页面动态数据替换效
果测试的访问实体类LoginController,内容如下。
@Controller
public class LoginController {
/**
* 获取并封装当前年份跳转到登录页login.html
*/
@GetMapping("/toLoginPage")
public String toLoginPage(Model model){
model.addAttribute("currentYear",
Calendar.getInstance().get(Calendar.YEAR));
return "login";
}
}
上文中,toLoginPage()方法用于向登录页面login.html跳转,同时携带了当前年份信息currentYear。
(4)创建模板文件并引入静态资源
在“classpath:/templates/”目录下创建一个用户登录的模板页面login.html,内容如下:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no">
<title>用户登录界面</title>
<link th:href="@{/login/css/bootstrap.min.css}" rel="stylesheet">
<link th:href="@{/login/css/signin.css}" rel="stylesheet">
</head>
<body class="text-center">
<!-- 用户登录form表单 -->
<form class="form-signin">
<img class="mb-4" th:src="@{/login/img/login.jpg}" width="72" height="72">
<h1 class="h3 mb-3 font-weight-normal">请登录</h1>
<input type="text" class="form-control" placeholder="用户名"
required="" autofocus="">
<input type="password" class="form-control" placeholder="密码" required="">
<div class="checkbox mb-3">
<label>
<input type="checkbox" value="remember-me"> 记住我
</label>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit">登录</button>
<p class="mt-5 mb-3 text-muted">© <span th:text="${currentYear}">2018</span>
-<span th:text="${currentYear}+1">2019</span></p>
</form>
</body>
</html>
上述代码中,先通过“xmlns:th=“http://www.thymeleaf.org””引入了Thymeleaf名称空间;然后,在代
码中使用“th:href”和“th:src”分别引入了两个外联的样式文件和一个图片;最后,在代码中使
用“th:text”引入了后台动态传递过来的当前年份currentYear。
上述代码示例中,引入了一些CSS样式文件和图片文件,为了保证页面美观效果,需要在项目的静态资
源文件夹static下创建相应的目录和文件(项目会提供源码信息和对应的样式文件,这里就不再详细展
示了),引入静态资源文件后项目结构如图所示:
(5)效果测试
启动项目进行测试,项目启动成功后,在浏览器上访问“http://localhost:8080/toLoginPage”进入用户
登录页面,效果如图所示。
从结果可以看出,登录页面login.html显示正常,在文中使用“th:*”相关属性引入的静态文件生效,并且
在页面底部动态显示了当前日期2019-2020,而不是文件中的静态数字2018-2019。这进一步说明了
Spring Boot与Thymeleaf整合成功,完成了静态资源的引入和动态数据的显示。
Freemarker模板引擎介绍
Freemarker是一款模板引擎,是一种基于模版生成静态文件的通用工具,它是使用纯java编写的,一般用来生成HTML页面。
${ }插值运算符
java中Freemarker插值就是${…}或#{…}格式的部分,将使用数据模型中的部分替代输出。
1. 插值结果为字符串值
直接输出表达式结果
2. 插值结果为数字值
根据默认格式(由#setting指令设置)将表达式结果转换成文本输出.可以使用内建的字符串函数格式化单个插值。
<#settion number_format="currency"/>
<#assign answer=42/> <!-- 自定义变量 -->
${answer}
${answer?string}
${answer?string.number}
${answer?string.currency}
${answer?string.percent}
${answer}
执行输出结果:
$42.00
$42.00
42
$42.00
4,200%
3. 插值结果为日期值
根据默认格式(由#setting指令设置)将表达式结果转换成文本输出.可以使用内建的字符串函数格式化单个插值。
${lastUpdated?string("yyyy-MM-dd HH:mm:ss zzzz")}
${lastUpdated?string("EEE, MMM d, ''yy")}
${lastUpdated?string("EEEE, MMMM dd, yyyy, hh:mm:ss a '('zzz')'")}
执行输出结果:
2008-04-08 08:08:08 Pacific Daylight Time
Tue, Apr 8, '03
Tuesday, April 08, 2003, 08:08:08 PM (PDT)
4. 插值结果为布尔值
根据默认格式(由#setting指令设置)将表达式结果转换成文本输出.可以使用内建的字符串函数格式化单个插值。
<#assign foo=true/>
${foo?string("yes", "no")}
执行输出结果:
yes
数字格式化插值:#{expr}或#{expr;format}
采用#{expr;format}形式来格式化数字,其中format可以是: 1. mX:小数部分最小X位 2. MX:小数部分最大X位。
<#assign x=2.582/>
<#assign y=4/>
#{x; M2}
#{y; M2}
#{x; m2}
#{y; m2}
#{x; m1M2}
#{x; m1M2}
执行输出结果:
2.58
4
2.6
4.0
2.58
4.0
避免空值插值
!: 指定缺失变量的默认值
${sss!} <#--没有定义这个变量,默认值是空字符串! -->
${sss!"abc"} <#--没有定义这个变量,默认值是字符串abc! -->
??:判断变量是否存在
variable??,如果变量存在,返回true,否则返回false。
插值规则
-
表达式放置在插值语法${ }之中,用于输出表达式的值。
-
表达式的值的类型可以是:字符串、 数字、布尔、日期时间、序列、Hash结构
-
表达式支持Java中的所有运算符:
- 算术运算符:+、-、*、/、%
- 比较运算符:==(eq)、!=(ne)、>(gt)、>=(gte)、<(lt)、<=(lte)
- 逻辑运算符:&&(and)、||(or)、!(not)
三目运算符:? :
- 算术运算符:+、-、*、/、%
-
内置函数:
-
使用方式:表达式?函数名[(实参)]
-
字符串的常用内置函数: substring(from[, to])、html、length、trim、url 示例:
<#setting url_escaping_charset="UTF-8"> 、exp?url[("UTF-8")]
-
数字的常用内置函数:c、string[(数字模式串)]、
-
布尔的内置函数:string[(“男”, “女”)]
-
内置的常用日期时间函数:string[(“格式模式串”)]、datetime、date、time
-
-
序列:
在FTL中定义的序列:由方括号包括,各元素用英文逗号分隔如:<#assign seq=["winter", "spring", "summer", "autumn"]>
也可以用数字范围(递增、反递增)定义数字序列:<#assign nums=101..105>
或<#assign nums=105..101>
在数据模型中可以是List对象、Set对象,序列的常用内置函数:size、sort[(“指定字段作排序依据”)] -
Hash结构:
在FTL文件中直接定义时:由大括号包括,由逗号分隔键/值列表,键和值之间用冒号分隔。键必须是字符串。如: <#assign scores={“语文”:78, “数学”:89, “英语”:87}> ${scores.语文} 在数据模型中可以是Map对象,Hash结构的内置函数:size、keys、values
例子
${book.name?if_exists } //用于判断如果存在,就输出这个值
${book.name!"xxx"} //默认值xxx
${book.date?string('yyyy-MM-dd')} //日期格式
${book?string.number} 20 //三种不同的数字格式
${book?string.currency} <#-- $20.00 -->
${book?string.percent} <#-- 20% -->
${.now?datetime} //当前时间戳
list指令
java Freemarker中list指令主要是进行迭代服务器端传递过来的List集合。
- 获取或者设置list相关信息
<#list animals as ani>
<!-- 获取list的size长度 -->
<div>${list?size}<div>
<!-- 获取list遍历中的下标序号 -->
<div>${ani_index}<div>
<!-- 遍历list的值 -->
<div>${ani.name}${ani.price}<div>
<!-- 是否是最后一个元素 -->
<#if !ani_has_next>
${ani.name}
</#if>
</#list>
- list排序
//升序:sort_by()
<#list list?sort_by("字段") as x>
</#list>
//降序:sort_by()?reverse
<#list list?sort_by("字段")?reverse as x>
</#list>
- list嵌套
<#list jsskList as jsskVO>
<#list kcList as kcVO>
<!-- kcVO里有编号和名称,而jsskVO里只有编号 -->
<#if kcVO.kch=jsskVO.kch>
${kcVO.kcm}
</#if>
</#list>
</#list>
- 判断list是否为空
freemarker中list判断是否为空一般有3种方式:
<#if 集合对象?exists>
<#if 集合对象??>
<#if 集合对象?default("xxx")>
<!-- 例子 -->
<#if orgList?? && (orgList?size > 0) >
list不为空
<#else>
list为空
</#if>
if else 指令
java Freemarker中if指令主要是做if判断用的,要注意的是条件等式必须用括号括起来。
定义
<#if condition>
...
<#elseif condition2>
...
<#elseif condition3>
...
<#else>
...
</#if>
-
condition,condition2等表达式将被计算成布尔值。
-
elseif 和 else必须出现在if的内部,也就是说,在if的开始标签和结束标签之间。
-
if中可以包含任意数量的elseif(包含0个),而且结束时else时可选的。
例子
<#if student.studentAge lt 12>
${student.studentName}不是一个初中生
<#elseif student.studentAge lt 15>
${student.studentName}不是一个高中生
<#elseif student.studentAge lt 18>
${student.studentName}不是一个大学生
<#else>
${student.studentName}是一个大学生
</#if>
<!-- 判断对象是否为null -->
<#if obj??>
obj不为空
<#else>
obj为空
</#if>
<!-- obj如果为空则给obj赋值xxx。 -->
<#if obj?default("xxx")>
如果student.studentAge为20,student.studentName为张三丰,执行结果如下:
张三丰是一个大学生
<#assign age=23>
<#if (age>60)>老年人
<#elseif (age>40)>中年人
<#elseif (age>20)>青年人
<#else> 少年人
</#if>
输出结果是:青年人
switch case指令
java Freemarker中switch是分支指令,作用类似于Java的switch语句。
定义
<#switch value>
<#case refValue>...<#break>
<#case refValue>...<#break>
<#default>...
</#switch>
- switch(expr),其中expr只能是一下两种:
- 枚举常量:内部是由整型或者字符类型实现
- 整数表达式:整数表达式指的是基本类型int或者包装类Integer,也包括不同的长度整型,例如short。
- case后面接的可以使常量数值,也可以是常量计算式,但是不能使变量或者是带有变量的表达式。
例子
<!-- 字符串用法-->
<#switch being.size>
<#case "small">
This will be processed if it is small
<#break>
<#case "medium">
This will be processed if it is medium
<#break>
<#case "large">
This will be processed if it is large
<#break>
<#default>
This will be processed if it is neither
</#switch>
<!-- 数字用法-->
<#switch x>
<#case 1>
1
<#case 2>
2
<#default>
d
</#switch>
如果x=1 输出 1 2, x=2 输出 2, x=3 输出d
include指令详解
java Freemarker中include指令用于导入文件,它可以在模版中插入其他的静态文件,或者是freemarker模版,这里通常引入的都是项目的公共部分,比如说网站的头部,以及版权信息等等。
定义
<#include path>
<#include path options>
path: 要包含文件的路径。可以使用相对路径和绝对路径。通常使用/(斜杠)来分割路径成分。(用其他话说, 它不用是一个固定的字符串,它也可以是像 profile.baseDir + “/menu.ftl” 这样的东西。)
options:一个或多个这样的选项(encoding=encoding, parse=parse)
encoding:算作是字符串的表达式。被包含文件从包含的文件继承的编码方式。(ISO-8859-2、UTF-8、GB2312)
parse:算作是布尔值的表达式。默认是true。如果它为真,那么被包含的文件将会当做FTL来解析,否则整个文件将被当成简单文本来处理。(也就是说不会在其中查找FreeMarker结构)
ignore_missing: 算作是布尔值的表达式
例子
<!--父页面ftl -->
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
<#include "/inc/top.ftl"/>
子页面你好
</body>
</html>
<!--子页面 top.ftl -->
<h1>欢迎,进入学生管理系统!</h1>
运行结果生成HTML页面:
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
<h1>欢迎,进入学生管理系统!\</h1>
子页面你好
</body>
</html>
总结
- 被包含模板的输出格式是在include标签出现的位置插入的。
- include被包含的文件和包含它的模板共享变量,就好像是被复制粘贴进去的一样。
- 这个指令不可与JSP(Servlet)的include搞混,因为它不涉及到Servlet容器中,只是处理另外一个FreeMarker模板,不能"离开"FreeMarker。
assign指令详解
java Freemarker中assign指令为该模板页面创建或替换一个顶层变量。
定义
//第一种方式
<#assign name=value [in namespacehash]>
用于指定一个名为name的变量,该变量的值为value,in子句用于将创建的name变量放入namespacehash命名空间中.
//第二种方式
<#assign name1=value1 name2=value2 ... nameN=valueN [in namespacehash]>
可以同时创建或替换多个顶层变量。
//第三种方式
<#assign name [in namespacehash]>
......
</#assign>
指将assign指令的内容赋值给name变量,主要用于创建或替换的变量值是一个复杂的表达式的这种情况。
例子
- assign替换变量值
<#assign x>
<#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"]as n>
${n}
</#list>
</#assign>
${x}
代码执行输出:
星期一 星期二 星期三 星期四 星期五 星期六 星期天
- assign迭代Map
<#-- 这里模拟了一个Map集合,定义了三对键值 -->
<#assign h = {"name":"mouse", "price":50, "weight":30}>
<#-- h?keys 调用了一个包装类的方法,将Map的key取出赋值 -->
<#assign keys = h?keys>
<#-- ${h[key]} 访问到了Map中的value属性 -->
<#list keys as key>${key} = ${h[key]}; </#list>
执行输出:
name = mouse; price = 50; weight = 30;
SpringBoot整合Freemarker模板引擎
导入依赖
<!--web启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--freemarker模板引擎-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
ml
<#assign x>
<#list [“星期一”, “星期二”, “星期三”, “星期四”, “星期五”, “星期六”, “星期天”]as n>
${n}
</#list>
</#assign>
${x}
代码执行输出:
星期一 星期二 星期三 星期四 星期五 星期六 星期天
2. assign迭代Map
```html
<#-- 这里模拟了一个Map集合,定义了三对键值 -->
<#assign h = {"name":"mouse", "price":50, "weight":30}>
<#-- h?keys 调用了一个包装类的方法,将Map的key取出赋值 -->
<#assign keys = h?keys>
<#-- ${h[key]} 访问到了Map中的value属性 -->
<#list keys as key>${key} = ${h[key]}; </#list>
执行输出:
name = mouse; price = 50; weight = 30;
SpringBoot整合Freemarker模板引擎
导入依赖
<!--web启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--freemarker模板引擎-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>