FreeMarker与Thymeleay详解

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:caseth: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:selectedselected选择框 选中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>

${…} 变量表达式

变量表达式功能

  1. 可以获取对象的属性和方法

  2. 可以使用ctx,vars,locale,request,response,session,servletContext内置对象

  3. 可以使用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下创建相应的目录和文件(项目会提供源码信息和对应的样式文件,这里就不再详细展
示了),引入静态资源文件后项目结构如图所示:

image-20201126192800872

(5)效果测试

启动项目进行测试,项目启动成功后,在浏览器上访问“http://localhost:8080/toLoginPage”进入用户
登录页面,效果如图所示。

image-20201126192908471

从结果可以看出,登录页面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。

插值规则

  1. 表达式放置在插值语法${ }之中,用于输出表达式的值。

  2. 表达式的值的类型可以是:字符串、 数字、布尔、日期时间、序列、Hash结构

  3. 表达式支持Java中的所有运算符:

    • 算术运算符:+、-、*、/、%
    • 比较运算符:==(eq)、!=(ne)、>(gt)、>=(gte)、<(lt)、<=(lte)
    • 逻辑运算符:&&(and)、||(or)、!(not)
      ​ 三目运算符:? :
  4. 内置函数:

    • 使用方式:表达式?函数名[(实参)]

    • 字符串的常用内置函数: substring(from[, to])、html、length、trim、url 示例:<#setting url_escaping_charset="UTF-8"> 、exp?url[("UTF-8")]

    • 数字的常用内置函数:c、string[(数字模式串)]、

    • 布尔的内置函数:string[(“男”, “女”)]

    • 内置的常用日期时间函数:string[(“格式模式串”)]、datetime、date、time

  5. 序列:
    在FTL中定义的序列:由方括号包括,各元素用英文逗号分隔如:<#assign seq=["winter", "spring", "summer", "autumn"]>也可以用数字范围(递增、反递增)定义数字序列: <#assign nums=101..105><#assign nums=105..101>在数据模型中可以是List对象、Set对象,序列的常用内置函数:size、sort[(“指定字段作排序依据”)]

  6. 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集合。

  1. 获取或者设置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>
  1. list排序
//升序:sort_by()
<#list list?sort_by("字段") as x>
</#list>
//降序:sort_by()?reverse
<#list list?sort_by("字段")?reverse as x>
</#list>
  1. list嵌套
<#list jsskList as jsskVO>
    <#list kcList as kcVO>
        <!-- kcVO里有编号和名称,而jsskVO里只有编号 -->
        <#if kcVO.kch=jsskVO.kch> 
            ${kcVO.kcm}
        </#if>
    </#list>
</#list>
  1. 判断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>
  1. condition,condition2等表达式将被计算成布尔值。

  2. elseif 和 else必须出现在if的内部,也就是说,在if的开始标签和结束标签之间。

  3. 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>
  1. switch(expr),其中expr只能是一下两种:
    • 枚举常量:内部是由整型或者字符类型实现
    • 整数表达式:整数表达式指的是基本类型int或者包装类Integer,也包括不同的长度整型,例如short。
  2. 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>

总结

  1. 被包含模板的输出格式是在include标签出现的位置插入的。
  2. include被包含的文件和包含它的模板共享变量,就好像是被复制粘贴进去的一样。
  3. 这个指令不可与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变量,主要用于创建或替换的变量值是一个复杂的表达式的这种情况。

例子

  1. assign替换变量值
<#assign x>
<#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"]as n>
${n}
</#list>
</#assign>
${x}

代码执行输出:

星期一 星期二 星期三 星期四 星期五 星期六 星期天
  1. 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>
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值