您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Model Center   Code  
会员   
   
 
     
   
 订阅
  捐助
Thymeleaf框架
 
作者:fmwind
  4105  次浏览      16
 2019-10-11
 
编辑推荐:
本文主要介绍了如何使用一个Spring项目来集成Thymeleaf以及Thymeleaf语言OGNL的基本使用方法,希望本文对您的学习有所帮助。
本文来自csdn,由火龙果软件桃子编辑、推荐。

简单说, Thymeleaf 是一个跟 Velocity、FreeMarker 类似的模板引擎,它可以完全替代 JSP 。相较与其他的模板引擎,它有如下三个极吸引人的特点:

1.Thymeleaf 在有网络和无网络的环境下皆可运行,即它可以让美工在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数据的动态页面效果。这是由于它支持 html 原型,然后在 html 标签里增加额外的属性来达到模板+数据的展示方式。浏览器解释 html 时会忽略未定义的标签属性,所以 thymeleaf 的模板可以静态地运行;当有数据返回到页面时,Thymeleaf 标签会动态地替换掉静态内容,使页面动态显示。

2.Thymeleaf 开箱即用的特性。它提供标准和spring标准两种方言,可以直接套用模板实现JSTL、 OGNL表达式效果,避免每天套模板、改jstl、改标签的困扰。同时开发人员也可以扩展和创建自定义的方言。

3. Thymeleaf 提供spring标准方言和一个与 SpringMVC 完美集成的可选模块,可以快速的实现表单绑定、属性编辑器、国际化等功能。

引入Thymeleaf

我们现在使用一个Spring项目来集成Thymeleaf。首先引入Thymeleaf的依赖项。thymeleaf-spring4会自动引入Thymeleaf核心包thymeleaf-core,因此我们只需要在项目中声明这一个依赖即可。

<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring4</artifactId>
<version>3.0.6.RELEASE</version>
</dependency>
<!--<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.0.6.RELEASE</version>
</dependency>-->

然后需要声明Thymeleaf的几个Bean,模板引擎、模板解析器和视图解析器。如果是开发过程中,可以关闭Thymeleaf页面缓存,这样可以让对页面的改动及时反映到视图中。

<bean id="templateResolver"
class="org.thymeleaf.spring4.templateresolver.Spring

ResourceTemplateResolver">
<property name="prefix" value="/WEB-INF/templates/"/>
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML5"/>
<!-- 缓存--><property name="cacheable" value="false"/>
</bean>

<bean id="templateEngine"
class="org.thymeleaf.spring4.SpringTemplateEngine">
<property name="templateResolver" ref="templateResolver"/>
</bean>
<bean class="org.thymeleaf.spring4.view.Thymeleaf
ViewResolver">
<property name="templateEngine" ref="templateEngine"/>
<property name="order" value="1"/>
<property name="characterEncoding" value="UTF-8"/>
</bean>

然后我们新建一个Thymeleaf页面,它和普通的HTML页面非常相似,只不过在html元素上需要添加xmlns:th="http://www.thymeleaf.org"属性。如果需要向页面传值的话,可以在控制器方法参数中添加Model对象,然后向其添加需要传递的对象。之后可以使用${var_name}在Thymeleaf中访问了。

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>主页</title>
</head>
<body>
<h1>你好</h1>
<h2 th:text="呵呵"></h2>
</body>
</html>

然后我们用一个视图控制器将/和主页绑定。

<mvc:view-controller path="/" view-name="index"/>

然后运行程序,访问主页,即可看到Thymeleaf的结果。

基本使用

Thymeleaf使用的是OGNL语言,如果和Spring集成的话,会改为使用Spring EL。不过这两者之间大部分是相同的。因此这里讨论的大部分使用OGNL语言方法对Spring EL也适用。

文本、字面值和国际化文本

文本

文本需要th:text属性来设置。我们可以在文本元素中添加默认值,这样当Thymeleaf引擎处理失败的时候页面会显示默认值。${...}是变量表达式,将括号中的变量替换为其值。

<p th:text="${hello}">你好<p>

字面值

在th:text中我们可以使用各种字面值,下面列举如下。

字符串字面值。如果需要连接多个字符串使用+即可。

<span th:text="'字符串字面值需要用单引号包括'">默认值</span>

数字字面量。我们可以使用运算符计算数字的值。

<span th:text="2012 + 5">2017</span>

布尔值字面量。

<p th:text="true==true"></p>

thymleaf读取内容中的html元素

利用<div th:text="${txt}">读取的数据库内容无法解析html元素,需要使用<div th:utext="${txt}"></div>

内插字符串

很多语言都支持内插字符串,可以方便的格式化字符串。不过Java不支持,这就比较蛋疼了。内插字符串可以将一个字符串中给定部分替换为实际字符串。内插字符串需要使用|包括,在|中只能包括${}表达式,不能包括其他表达式。

<span th:text="|你好, ${name}!|">

上面的内插字符串等效于下面的一段。

<span th:text="'你好, ' + '${name}' + '!'">

算术、比较和逻辑运算

在Thymeleaf中可以进行常见的各种算术运算。如果使用除/或者取余%运算符的话,还可以使用div或mod代替。

<p th:text="(17%5)-2"></p>

也可以进行比较和逻辑运算。由于<这样的符号用在了HTML标签中。所以在Thymeleaf中需要使用gt等代替。比较和逻辑运算符有gt (>), lt (<), ge (>=), le (<=), not (!), eq (==), neq/ne (!=) 。

<p th:text="1 gt 2"></p>

条件表达式

这个和Java中的三元条件表达式:一样。

<p th:text="true?'真':'假'"></p>

默认表达式

这也是一个非常方便的特性,在C#和一些语言中提供。默认表达式是val1 : val2,给定两个变量,当前面一个不是空的时候,前面的值会被使用,否则后面的值作为默认值被使用。

<p th:text="null?:'我不是空值'"></p>

它可以用三元条件表达式替换。

<p th:text="${val}!=null?${val}:'我不是空值'"></p>

无操作标记

无操作标记是下划线_,Thymeleaf遇到该标记的时候不会进行任何操作。

<p th:text="_">不进行任何操作</p>

生成链接

Thymeleaf也可以生成URL,类似JSTL中的<c:url>标签。这需要使用另外一种类型的表达式@{...},表示其中的是URL。支持的URL有绝对路径(完整的URL),Servlet环境相对路径(/showUsers这样的)、服务器相对路径(~/myapp/showUser这样的,允许我们调用同一个服务器下其他Servlet环境中的URL)、协议相对路径(//code.jquery.com/jquery-2.0.3.min.js)。

下面是简单的一个例子。

<p><a th:href="@{/}">返回主页</a></p>

假如需要在链接中包含查询参数,可以在@{}中使用括号,有多个查询参数使用逗号分隔开。下面这个例子最终会生成类似/helloname=易天&age=23这样的链接。

<p><a th:href="@{/hello(name='易天',age=23)}">问候</a></p>

如果需要路径参数的话,也是类似的,只不过路径参数需要括号包括起来。

<p><a th:href="@{/hello/{name}(name='易天')}">问候</a></p>

这些链接会由org.thymeleaf.linkbuilder.ILinkBuilder接口处理,转换为实际的URL。Thymeleaf的默认实现org.thymeleaf.linkbuilder.StandardLinkBuilder可以用于非Web环境和Servlet环境。如果使用其他框架的话Thymeleaf可能不能正确生成URL,这时候就需要查阅相关文档了。

根据变量值动态添加样式:

<a th:style="${menu=='1''color:#0663C9':''}"菜单1</a>//如果menu值得1,则该菜单被选中

使用Thymeleaf表达式

前面用到的主要是${...},用来获取变量的值。除了美元表达式之外,Thymeleaf还有其他表达式,以下会逐一介绍。

表达式基本对象

Thymeleaf包含了一些基本对象,可以用于我们的视图中。这些基本对象使用#开头。

#ctx: 上下文对象.

#vars: 上下文变量.

#locale: 区域对象.

#request: (仅Web环境可用)HttpServletRequest对象.

#response: (仅Web环境可用)HttpServletResponse对象.

#session: (仅Web环境可用) HttpSession对象

#servletContext: (仅Web环境可用)ServletContext对象.

几个Web相关的对象会被Thymeleaf映射为Thymeleaf上下文中的对象,因此我们不需要也不能在它们前面添加#。例如如果我们要引用Session中的值,可以像这样使用。

<p th:text="${session.user}"></p>

表达式工具对象

这些对象同样以#开头,包含了各种工具方法,可以执行格式化、转换、生成URL等各种操作。由于这些工具对象比较多,所以我在这里就不介绍了。如果需要详细了解,可以查看表达式工具对象文档。Thymeleaf文档附录B列出这些对象的使用方法。

选择表达式(星号语法)

星号表达式和美元表达式的作用都是求变量的值。不过它们之间有一些区别,星号表达式作用于被选择的对象。被选择的对象需要使用th:object指定。下面是Thymeleaf的一个例子。

<div th:object="${session.user}">
<p>Name: <span th:text="*{firstName}">Sebastian</span>.</p>
<p>Surname: <span th:text="*{lastName}">Pepper</span>.</p>
<p>Nationality: <span th:text="*{nationality}">Saturn</span>.</p>
</div>

等效于使用${..}。

<div>
<p>Name: <span th:text="${session.user.firstName}">Sebastian</span>.</p>
<p>Surname: <span th:text="${session.user.lastName}">Pepper</span>.</p>
<p>Nationality: <span th:text="${session.user.nationality}">Saturn</span>.</p>
</div>

当存在选择对象的时候,我们可以使用美元表达式${#object}来访问选择对象,也可以同时使用星号表达式和美元表达式。选择表达式的主要作用是在表达式比较长例如${session.users.address.street.fullname}的时候,简化表达式。

类型转换和格式化

当使用双括号包括的变量${{...}}或者*{{...}}时,Thymeleaf会使用它的IStandardConversionService来将变量转换为字符串。Thymeleaf默认的实现只是简单地调用了toString方法。如果使用了thymeleaf-spring4包和Spring集成的话,Thymeleaf会自动使用Spring的ConversionService来进行转换。

包含头部和底部页面

一般来说,一个网站的各个网页中的导航栏,页尾,菜单等部分都是相同或相似的,可以将这部分代码提取成模板供其它页面使用。

要实现该功能,可以使用Thymeleaf模板的 th:replace、th:include或th:insert属性,借助th:fragment属性来实现。

被包含页面:

<ul class="main_dh" th:fragment="menu" xmlns:th="http://www.w3.org/1999/xhtml">
<li><a th:href="@{/main/index}">网站首页</a></li>
<li ><a th:style="${menu=='1'?'color:#0663C9':''}" th:href="@{/course/main/queryById/1/{cid}(cid=${session.cid})}">课程简介</a></li>
<li><a th:style="${menu=='2'?'color:#0663C9':''}" th:href="@{/course/main/queryById/2/{cid}(cid=${session.cid})}">教学大纲</a></li>
<li><a th:style="${menu=='3'?'color:#0663C9':''}" th:href="@{/teacher/main/queryAll/{cid}(cid=${session.cid})}">教学队伍</a></li>
<li><a th:style="${menu=='4'?'color:#0663C9':''}" th:href="@{/cw/main/queryAll/1/{cid}(cid=${session.cid})}">教学课件</a></li>
<li><a th:style="${menu=='5'?'color:#0663C9':''}" th:href="@{/cw/main/queryAll/3/{cid}(cid=${session.cid})}">教学视频</a></li>
<li><a th:style="${menu=='6'?'color:#0663C9':''}" th:href="@{/cw/main/queryAll/2/{cid}(cid=${session.cid})}">在线习题</a></li>
</ul>

包含页面:

<div class="con_main">
<div class="top">
<span class="top_title"><label th:text="${session.cname}"></label><i>—精品课程</i></span>
</div>
<div th:replace="main/menu::menu"></div>

<div class="main_con_team">
<ul class="online_ul" th:each="cw : ${list}">
<li> <label th:text="${cw.cwName}"></label><a th:href="@{/cw/main/downloadFile/{cwId}(cwId=${cw.cwId})}" >下载</a></li>
</ul>
</div>
<div th:replace="main/footer::copy"></div>
</div>

设置标签属性

有时候我们需要设置某些页面元素的属性(例如按钮)。在JSP中我们需要编写这样的代码<input type="button" value="${msg}">。在Thymeleaf中非常简单。

<input th:attr="type='button',value='${msg}'">

如果需要设定某个特定的属性。可以这样。

<input th:type="button" th:value="${msg}">

前面生成超链接的代码其实也是一样的,只不过属性是href、

<p><a th:href="@{/}">返回主页</a></p>

这些特定的属性有很多,详见Thymeleaf文档 设置特定属性的值。

还有特殊的属性,可以同时设置两个值。它们分别是th:alt-title和th:lang-xmllang,在设置图片和语言属性的时候非常有用。

有时候需要向已有的属性中添加新的值(例如在Bootstrap中卫按钮设置不同的颜色)。这可以通过th:attrappend和th:attrprepend向后或向前添加属性。

<input type="button" value="warn" class="btn" th:attrappend="class=${' ' + style}" />

条件选择块

在开发Web程序的时候, 很常见的需求就是根据某个值的真假,显示或隐藏某个HTML元素。这可以使用th:if="${exp}"实现。需要注意和JSTL中的<c:if>不同,Thymeleaf会根据条件显示或隐藏包含th:if的整个标签块,而不仅是它的子标签块。

<div th:if="true">....</div>

需要注意th:if的表达式不仅支持Java式的纯条件判断,还支持C语言式的真值判断,即当一个变量不为空或者整数不是0的时候,也认为是真值。另外还有一个th:unless执行和th:if相反的判断。

多重选择块

如果需要多重选择,可以使用th:switch。需要注意一旦有一个子条件匹配,Thymeleaf就不会继续检查其他条件了。如果需要提供默认值的话,可以这样写,th:case="*"。

<div th:switch="${number}">
<p th:case="1'">这是1</p>
<p th:case="2">这是2</p>
<p th:case="*">其他值</p>
</div>

迭代块

有时候我们需要遍历一个数组中的元素。这可以使用th:each实现。在th:each中我们要指定迭代元素和被迭代集合。被迭代集合可以是:数组,任何实现了java.util.Iterable的对象,任何实现了java.util.Enumeration的对象,任何实现了java.util.Iterator的对象,任何实现了java.util.Map的对象。需要注意的是,和JSTL的<c:forEach>标签不同,Thymeleaf会迭代包含<th:each>的整个标签块,而不仅仅是它的子标签块。

<tr th:each="user : ${users}">
<td th:text="${user.name}"></td>
<td th:text="${user.age}"></td>
<td th:text="${user.birthday}"></td>
</tr>

Thymeleaf还提供了迭代状态变量来检测当前迭代的状态,只需要在th:each中声明iterStat即可。假如没有显式声明状态变量,Thymeleaf也会创建一个状态变量,名称是迭代元素添加后缀Stat。上面的代码中,Thymeleaf会创建一个名为userStat的状态变量。

<tr th:each="user,iterStat : ${users}">
<td th:text="${user.name}"></td>
<td th:text="${user.age}"></td>
<td th:text="${user.birthday}"></td>
</tr>

状态变量包含以下属性;

index属性,以0开始的迭代元素索引。

count属性,以1开始的迭代元素索引。

size属性,迭代集合的总元素数。

iter属性,当前迭代元素。

even和odd两个布尔值,表明当前index的奇偶。

first和last两个布尔值,表明当前元素是否是第一个/最后一个。

国际化文本

默认情况下,我们可以在与视图文件相同的目录下编写properties文件,然后使用消息语法#{home.welcome}来引用文件中的字符串。可以有多个属性文件,对应不同的区域,例如home_en.properties代表英文区域,home_es.properties代表西班牙区域。下面是一个示例属性文件。

home.welcome=你好

默认情况下Thymeleaf会在与视图相同的文件下寻找同名的属性文件来加载消息。我们也可以自定义消息解析器,用自己的策略从任何地方加载消息。

代码段

定义代码段

首先我们来定义一个代码段。假设文件名叫做_header.html,该文件的内容如下。在文件中我们使用th:fragment定义了一个代码段。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="header">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link th:href="@{/static/css/bootstrap.css}" rel="stylesheet"/>
<link th:href="@{/static/css/bootstrap-theme.css}" rel="stylesheet"/>
<script th:href="@{/static/js/jquery.js}"></script>
<script th:href="@{/static/js/bootstrap.js}"></script>
</th:block>
</head>
<body>
</body>
</html>

使用代码段

然后在其他地方,我们就可以使用th:insert或th:replace来插入代码段了。这两者的区别是th:insert会将代码段插入该元素内部,而th:replace会将整个元素替换为要插入的代码块。在这里又出现了一种新语法~{file :: fragment},表示引用文件的某个代码块。

另外~{..}是可选的,所以上面的代码还可以写为下面的形式。

<head th:replace="_header :: head">

代码段表达式的第一个参数可以省略(~{::selector})或者写为this(~{this::selector}),表示要引用的代码段就在当前文件中。表达式的第二个参数可以是代码段的名称,也可以是CSS选择器(~{file::#form})。如果不指定第二个参数的话,就会引入整个文件(~{templatename})。

参数化代码段

代码段可以有参数,折让它拥有类似函数的行为。下面是一个例子。

<head th:fragment="header(title)">
<title th:text="${title}"></title>
</head>

要引入代码块的时候,同样指定参数即可。

<head th:replace="_header::header('问候')">

</head>

如果有多个参数,用逗号分隔即可。在使用代码块的时候,既可以按照位置传入参数,也可以按照名称传入参数。

<div th:replace="::frag (${value1},${value2})">...</div>
<div th:replace="::frag (onevar=${value1},twovar=${value2})">...</div>

块代码段

前面的代码段全部在某个页面元素中。如果代码块是一些平级的元素,又该怎么做呢?Thymeleaf提供了唯一的一个Thymeleaf块级元素<th:block>,可以帮助我们完成这一工作。首先创建一个_footer.html文件,在其中使用<th:block>创建一个代码块。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
</head>
<body>
<th:block th:fragment="footer">
<br>
<p>这是页脚</p>
</th:block>
</body>
</html>

然后在其他地方一样使用即可。Thymeleaf模板引擎在处理<th:block>的时候会删掉它本身,而保留其内容。

<div th:replace="_footer::footer"></div>

灵活的代码段配置

Thymeleaf的这些特性让它可以配置非常灵活的代码段。来看看Thymeleaf的这个例子。首先我们定义一个公用代码段。注意这里的links,它是一个Thymeleaf块,会被实际传入的参数替代。

<head th:fragment="common_header(title,links)">
<title th:replace="${title}">默认标题</title>
<!-- 公用CSS和JS文件 -->
<!--/* 各页面单独的文件 */-->
<th:block th:replace="${links}" />
</head>

然后引用代码段。注意这里的两个代码块参数,会直接选择本页面的所有标题和link标签,然后将它们传入公用代码段中。最后生成的结果大家可以想象一下,是不是非常的灵活呢?

<head th:replace="base :: common_header(~{::title},~{::link})">
<title>Awesome - Main</title>
<link rel="stylesheet" th:href="@{/css/bootstrap.min.css}">
<link rel="stylesheet" th:href="@{/themes/smoothness/jquery-ui.css}">
</head>

空代码段和无操作符

还是上面这个例子。如果我们传入空代码段,那么实际结果中相应的地方就会为空。

<head th:replace="base :: common_header(~{::title},~{})">

如果使用无操作符,那么实际生成的代码相应部分不会做任何Thymeleaf替换,也就是说会我们会得到默认标题。

<head th:replace="base :: common_header(_,~{::link})">

删除代码段

以下是Thymeleaf的一个例子。我们可以使用th:remove来删除指定的部分,这在原型设计和调试的时候很有用。

<tr th:remove="all">
<td>Mild Cinnamon</td>
<td>1.99</td>
<td>yes</td>
<td>
<span>3</span> comment/s
<a href="comments.html">view</a>
</td>
</tr>

th:remove可接受的值有5个:

all: 移除标签和所有子元素

body: 移除所有子元素,保留标签

tag: 移除标签,保留子元素

all-but-first: 保留第一个子元素,移除所有其他

none : 什么也不做。这个值在动态求值的时候会有作用

其他特性

由于Thymeleaf的用法很多,这里没办法完全写下,所以我就不写了。前面这些应该可以满足基本需求了。如果需要其他特性的话请看官方文档吧。这里简单的说明一下未详细介绍的其他特性。

本地变量

使用th:with声明一个本地变量,可以在某段代码中重用变量。

属性处理

Thymeleaf是如何处理这些th:*属性的呢?

注释和代码块

这里介绍了几种Thymeleaf注释。利用这些注释,我们可以让某些代码在原型设计的时候出现,某些代码在Thymeleaf引擎处理之后出现,等等。

内联

前面所有这些Thymeleaf属性都是使用属性方式写入的,能不能通过内联的方式直接在元素内部添加值?当然可以,只不过这样的话,当显示未处理的页面时,就不会显示预设的默认值,而是丑陋的表达式代码了。除此之外,还可以对CSS、JavaScript内联,让Thymeleaf引擎生成合适的代码。

模板模式

有HTML5、XML、TEXT等多种模式,可以用于生成各种类型的文档。

Thymeleaf配置

模板解析器、消息解析器、类型转换器、日志服务、缓存的配置方法。

 

   
4105 次浏览       16
相关文章

Java微服务新生代之Nacos
深入理解Java中的容器
Java容器详解
Java代码质量检查工具及使用案例
相关文档

Java性能优化
Spring框架
SSM框架简单简绍
从零开始学java编程经典
相关课程

高性能Java编程与系统性能优化
JavaEE架构、 设计模式及性能调优
Java编程基础到应用开发
JAVA虚拟机原理剖析