thymeleaf学习总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq877507054/article/details/84236224

.介绍

1.什么是thymeleaf

Thymeleaf是现代化服务器端的Java页面模板引擎,不同于JSP和FreeMarker,Thymeleaf的语法更加接近HTML,

 

2.为什么使用thymeleaf

springboot官方的支持与推荐

Spring Boot为以下的模板引擎提供自动配置支持:

1.FreeMarker

2.Groovy

3.Thymeleaf

4.Velocity(1.4已不再支持)

5.Mustache

 

 

注:由于在内嵌servlet容器中使用JSPs存在一些已知的限制,所以建议尽量不使用它们。

使用以上引擎中的任何一种,并采用默认配置,则模块会从 src/main/resources/templates 自动加载。

 

引用:Spring Boot参考指南

 

 

ThymeLeaf是一个健康的开源项目:每个月都有新的特性、良好的文档、响应性的用户论坛

如果您希望web设计器能够读取视图文件,那么它是理想的模板引擎。所使用的表达式语言(实际上称为标准方言)比JSP表达式语言强大得多。与JSP不同,Thymeleaf适用于富HTML电子邮件(参见http://www.thymeleaf.org/springmail.html).

 

引用:SpringMVC:从JSP和Tiles到Thymeleaf

 

 

3.怎么使用

<html xmlns:th="http://www.thymeleaf.org">

 

 

 

 

本文侧重点是总结和讲解thymeleaf的常用标签,表达式及表达式对象的使用

 

二.常用标签的用法

 

th:text 

th:text 用于文本的显示,并且可以进行简单的计算。

<td  th:text="${username}">mlm</td> -> <td>maliming</td>

<td  th:text="9+7">2018</td> -> <td>16</td>

 

th:utext

th:utext 用于html的文本替换,常用于富文本编辑器编辑后的内容显示到前台页面上。

<p th:utext="${article.content}"></p> -> <p>my name is <b>maliming</b></p>

 

th:if

th:if 用于判断条件,还可以多条件 and,or(二元操作符),!,not非(一元操作符)。

<div th:if="${user} != null">show</div>如果user对象为空则不显示,不为空则显示 -> <div>show</div>

 

<div th:if="${user} != null and ${otherUser} != null">show</div> 

 

不能用"<",">"等符号,要用"lt"等替代

 

运算符还可以写在${}里<div th:if="${user.number > 100}">show</div> -> <div>show</div> 运算符放在了 {} 内部, 此时整个 {} 内的表达式用 ognl/spel 引擎计算; 如果运算符放在外部, 那么 thymeleaf 引擎负责计算。

 

运算符扩展

进制运算符:+,-,\*,/,%

负号:-

二进制运算符:and 、or

布尔否定:!,not

比较运算符:>,<,> =,<=(gt,lt,ge,le)

相等运算符:==,!=(eq,ne)

字符串连接:+

文本替换:|The name is ${name}|

条件运算符:

   If-then:\(if\) ? \(then\)

   If-then-else:\(if\) ? \(then\) : \(else\)

   Default:\(value\) ?: \(defaultvalue\)

 

 

 

 

th:unless

 th:unless 用于判断条件,与th:if作用相反。

<div th:if="${user} != null">show</div>如果user对象不为空则不显示,为空则显示 -> <div>show</div> 

 

 

 

th:switch th:case

th:switch th:case 用于多个同等级相同目的判断,多选一时使用。

<div th:switch="${user.name}">

 

    <p th:case="maliming">first</p>若${user.name}中的值为maliming则显示,否则不显示

 

    <p th:case="${otherUser.name}">second</p>

 

</div>

 

 

 

th:action

th:action 用于定义后台控制器的路径,表单的提交地址,相当于<form>标签的action属性。

<form th:action="@{user/login}" method="post"></form>

 

 

 

th:each

th:each 用于遍历集合中的对象,相当于jstl中的<c:forEach>标签。

List集合循环遍历

 

<tr th:each="user,userStat:${messages.list}">

    <td th:text="${user.name}"></td>

    <td th:text="userStat.index"></td>

</tr>

 

其中的user是临时变量,相当于for(User user : users)中的user,userStat称为状态变量,属性有index:当前迭代对象的index(从0开始计算),count: 当前迭代对象的index(从1开始计算), size:被迭代对象的大小,current:当前迭代变量,even/odd:布尔值,当前循环是否是偶数/奇数(从0开始计算), first:布尔值,当前循环是否是第一个,last:布尔值,当前循环是否是最后一个。

 

Map集合循环遍历

<div th:each="map:${maps}" th:text="${map}"></div>

数组循环遍历

<tr>

    <td th:each="array:${arrays}" th:text="${array}"></td>

</tr>

 

 

th:value

 th:value 用于属性赋值。

<option th:value="${user.name}"></option> -> <option value="maliming"></option>

 

 

th:src

th:src 用于外部资源的引入,例如图片,js文件。

<img th:src="@{../images/myself.jpg}"/>或<script th:src="@{../static/login.js}"></script>

 

 

th:href

th:href 用于定义超链接,相当于<a></a>标签的href属性。

<a th:href="@{/user/selectUser?(currentPage=1,reTypeid=${reTypeid},inquiry=${inquiry})}"></a> 传参。

 

 

th:remove

th:remove 用于删除。可以表达式传参。

<table border="1">  

    <thead>  

          <tr>  

             <th>编号</th>  

             <th>用户名</th>    

             <th>姓名</th>   

             <th>性别</th>  

          </tr>  

    </thead>  

    <tbody th:remove="all-but-first" 或者表达式th:remove="${choice}? all : all-but-first">  

          <tr>  

             <td>1</td>  

             <td>[email protected]</td>  

             <td>Tom</td>  

             <td>男</td>  

          </tr>  

          <tr>  

             <td>3</td>  

             <td>[email protected]</td>  

             <td>Lucy13</td>  

             <td>女</td>  

           </tr>  

     </tbody>

</table>  

 

 

这里的<tbody></tbody>标签中有th:remove="all-but-first",意思是只保留<tbody></tbody>标签中的第一个字标签,也就是name为Tom的所在<tr></tr>,其他的子标签则会删除,th:remove有五个属性值。

all:删除所在标签和内容及其所属的所有子标签。body:删除所在标签的内容及其所属的所有子标签。tag:删除所在标签,不删除任何所属的子标签。all-but-first:删除除第一个子标签外的其他子标签。none:不起作用,什么也不做。

th:selected

th:selected 用于选择框设置选中值。通常和th:each一起使用。

<select

    <option th:selected="${user.name} == ${otherUser.name}"></option> 若相等就默认选<option></option>

 

</select>

 

 

 

 

th:object

1.13 th:object 用于表单数据对象绑定,后台controller中参数保持一致,和选择(星号)表达式。

<form th:object="${user}">

    <input th:value="*{name}"/> *号代替了${user}

</form>

public ModelAndView addUser(@RequestParam(value = "user") User user,ModelMap model){}

 

 

 

 

th:attr

th:attr 用于设置任意属性

<input th:attr="value=${user.name}"/> 设置单个属性。

<input th:attr="value=${user.username},name=username"/> 设置多个属性之间用逗号隔开。

 

 

th:fragment

在我们的模板中,我们经常希望从其他模板中包含某些部分,如页脚,页眉,菜单等部分

为了做到这一点,Thymeleaf需要我们定义这些部分“片段”,以供其他模版包含,可以使用th:fragment属性来定义被包含的模版片段。

<!DOCTYPE html>

<html xmlns:th="http://www.thymeleaf.org">

<body>

<div th:fragment="copy">

© 2011 The Good Thymes Virtual Grocery

</div>

</body>

</html>

上面的代码定义了一个名为copy的片段,我们可以使用th:insert或th:replace属性(以及th:include,尽管Thymeleaf 3.0不再推荐使用它),容易地包含在我们的主页中:

<body>

...

<div th:insert="~{footer :: copy}"></div>

</body>

 

 

请注意,th:insert期望一个片段表达式(〜{...})。 在上面的例子中,这是一个简单的片段表达式,(〜{,})包围是完全可选的,所以上面的代码将等价于:

<body>

...

<div th:insert="footer :: copy"></div>

</body>

fragment加载语法如下:

templatename::selector:”::”前面是模板文件名,后面是选择器

::selector:只写选择器,这里指fragment名称,则加载本页面对应的fragment

templatename:只写模板文件名,则加载整个页面

 

模板名和选择器都可以是表达式(甚至是条件表达式!)

<div th:insert="footer :: (${user.isAdmin}? #{footer.admin} : #{footer.normaluser})"></div>

也可以使用th:replace

th:insert和th:replace(th:include)之间的区别

th:insert和th:replace之间有什么区别?(th:include在3.0之后不推荐使用了)?

th:insert是最简单的:它将简单地插入指定宿主标签的标签体中。

th:replace实际上用指定的片段替换其宿主标签。替换当前标签为模板中的标签,加载的节点会整个替换掉加载他的div

th:include类似于th:insert,⽽而不是插入片段,它只插入此片段的内容。

 

可参数化的片段签名

为了使模板片段具有多类似函数的功能,用th:fragment定义的片段可以指定一组参数:

<div th:fragment="frag (onevar,twovar)">

<p th:text="${onevar} + ' - ' + ${twovar}">...</p>

</div>

可以通过以下两种语法中的一种来引用上述模版⽚段,下面的th:replace改成th:insert也是一样的:

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

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

 

不带段参数的段局部变量

即使片段没有定义参数:

<div th:fragment="frag">

...

</div>

 

 

我们可以使用上面指定的第二个语法来调用它们(只有第二个语法才可以):

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

 

上面的代码等价于th:replace和th:with的组合:

<div th:replace="::frag" th:with="onevar=${value1},twovar=${value2}">

 

请注意,片段的局部变量规范 - 无论是否具有参数签名 - 都不会导致上下

文在执行之前被清空。片段仍然能够访问调用模板中正在使用的每个上下文变量。

由于片段表达式的强大功能,我们不仅可以为片段指定文本类型,数字类型,bean对象类型的参数,还可以指定标记片段作为参数。

这允许我们以一种方式创建我们的片段,使得它们可以调用户模板的标记,从而产生非常灵活的模板布局机制。

请注意在下面的片段中使用标题和链接变量:

<head th:fragment="common_header(title,links)">

<title th:replace="${title}">The awesome application</title>

 

<!-- Common styles and scripts -->

<link rel="stylesheet" type="text/css" media="all" th:href="@{/css/awesomeapp.css}">

<link rel="shortcut icon" th:href="@{/images/favicon.ico}">

<script type="text/javascript" th:src="@{/sh/scripts/codebase.js}"></script>

 

<!--/* Per-page placeholder for additional links */-->

<th:block th:replace="${links}" />

</head>

 

我们现在调用这个片段:

<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>

 

结果将使用调用模板中的实际<title>和<link>标签作为标题和链接变量的值,导致我们的⽚段在插入期间被定制化:

<head>

<title>Awesome - Main</title>

<!-- Common styles and scripts -->

<link rel="stylesheet" type="text/css" media="all" href="/awe/css/awesomeapp.css">

<link rel="shortcut icon" href="/awe/images/favicon.ico">

<script type="text/javascript" src="/awe/sh/scripts/codebase.js"></script>

<link rel="stylesheet" href="/awe/css/bootstrap.min.css">

<link rel="stylesheet" href="/awe/themes/smoothness/jquery-ui.css">

</head>

 

 

 

th:block

Thymeleaf标准方言中唯一的元素处理器(不是属性)是:th:block。

th:block是一个只允许模板开发人员指定他们想要的属性的属性容器。

Thymeleaf将执行这些属性,然后简单地制作块。

所以它可能是有用的,例如,当为每个元素创建多个<tr>的迭代表时:

<table>

  <th:block th:each="user : ${users}">

    <tr>

        <td th:text="${user.login}">...</td>

        <td th:text="${user.name}">...</td>

    </tr>

    <tr>

        <td colspan="2" th:text="${user.address}">...</td>

    </tr>

  </th:block>

</table>

 

 

 

 

th:inline

Thymeleaf模板中的三个模板被认为是问本:TEXT,JAVASCRIPT和CSS。 这将它们与标记模板模式区分开来:HTML和XML。

文本模板模式和标记模式之间的关键区别在于,在文本模板中,没有标签以属性的形式插⼊逻辑,因此我们必须依赖其他机制。最基本的机制是内联, 内联语法是以文本模板模式输出表达式结果的最简单方法,因此邮件形式模板来说,内联是最好的机制。

内联文本

<p th:inline="text">Hello, [[#{test}]]</p>

 

内联JavaScript

<script th:inline="javascript">

    ...

    var username = [[${session.user.name}]];

    ...

</script>

 

内联CSS

Thymeleaf还允许在CSS <style>标签中使⽤内联,如:

 

<style th:inline="css">

  ...

</style>

 

例如,假设我们有两个变量设置为两个不同的String值:

classname = 'main elems'

align = 'center'

我们可以这样做:

<style th:inline="css">

    .[[${classname}]] {

      text-align: [[${align}]];

    }

</style>

输出结果如下:

<style th:inline="css">

    .main\ elems {

      text-align: center;

    }

</style>

 

 

 

 

 

 

三.表达式

变量表达式:$ {...}

 

选择变量表达式:* {...}

 

消息表达式:#{...}

 

链接网址表达式:@ {...}

 

片段表达式:〜{...}

 

变量表达式 ${}

<input type="text" name="userName" value="James Carrot" th:value="${user.name}" />

上述代码为引用user对象的name属性值

 

 

选择表达式*{}

我们不仅可以将变量表达式写为$ {...},还可以作为* {...}。

这两种方式有一个重要的区别:星号语法计算所选对象而不是整个上下⽂

的表达式。 也就是说,只要没有选定的对象,$和*语法就会完全相同。

什么是选定对象? 使用th:object属性的表达式的结果。 我们在用户个⼈

资料(userprofile.html)页面中使用一个:

 <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}">Sebas

tian</span>.</p>

  <p>Surname: <span th:text="${session.user.lastName}">Pep

per</span>.</p>

  <p>Nationality: <span th:text="${session.user.nationalit

y}">Saturn</span>.</p>

</div>

 

选择表达式一般跟在th:object后,直接取object中的属性

 

URL表达式 @{}

 

<a href="details.html" th:href="@{/order/details(orderId=${o.id})}">view</a>

@{... ...}支持决定路径和相对路径。其中相对路径又支持跨上下文调用url和协议的引用

当URL为后台传出的参数时,代码如下:

 

<img src="../../static/assets/images/qr-code.jpg" th:src="@{${path}}" alt="二维码" />

 

片段表达式〜{}

代码片段表达式是表示标记片段的简单方法,并将其移动到模板周围。

这允许我们复制它们,将它们传递给其他模板作为参数,等等。

最常用的用法是使⽤th:insert或th:replace进行片段插入:

<div th:insert="~{commons :: main}">...</div>

 

它们可以在任何地方使用,就像任何其他变量一样:

<div th:with="frag=~{footer :: #main/text()}">

  <p th:insert="${frag}">

</div>

 

 

 

 

文字国际化表达式 #{}

 

<p th:utext="#{home.welcome}">Welcome to our grocery store!</p>

调用国际化的welcome语句,国际化资源文件如下

resource_en_US.properties:home.welcome=Welcome to here!

resource_zh_CN.properties:home.welcome=欢迎您的到来!

 

 

 

 

 

四.表达式对象

我们已经提到$ {...}表达式实际上是在上下中包含的变量的映射上执的OGNL(Object-Graph Navigation Language)对象

${} 中预存对象(表达式中基本对象)

 

基本表达式对象

当对上下文变量计算OGNL表达式时,某些对象可用于表达式以获得更高的灵活性。 这些对象将被引用(按照OGNL标准),从#符号开始(请注意,这些对象不是Map集合/命名空间):

 

#ctx:上下文对象。

#locale:上下文区域设置。

#vars:上下文变量。

#request :(仅在Web Contexts中)HttpServletRequest对象。

#session :(仅在Web上下文中)HttpSession对象。

#servletContext :(仅在Web上下文中)ServletContext对象。

#response:(仅在Web上下文中)HttpServletResponse对象。

 

#ctx:上下文对象。 根据我们的环境(独立环境或Web环境),实现org.thymeleaf.context.IContext或org.thymeleaf.context.IWebContext。

${#ctx.locale}

${#ctx.variableNames}

${#ctx.request}

${#ctx.response}

${#ctx.session}

${#ctx.servletContext}

 

#locale:直接访问与当前请求关联的java.util.Locale。 ${#locale}

...

#request:直接访问与当前请求关联的javax.servlet.http.HttpServletRequest对象。

${#request.getAttribute('foo')}

${#request.getParameter('foo')}

${#request.getContextPath()}

${#request.getRequestName()}

 

 

#session:直接访问与当前请求关联的javax.servlet.http.HttpSession对象。

${#session.getAttribute('foo')}

${#session.id}

${#session.lastAccessedTime}

...

 

#servletContext:直接访问与当前请求关联的javax.servlet.ServletContext对象。

${#servletContext.getAttribute('foo')}

${#servletContext.contextPath}

...

 

 

 

request和session属性的web命名空间

在Web环境中使用Thymeleaf时,我们可以使用一系列快捷方式来访问请求参数,会话属性和应用程序属性:

注意:这些不是上下文对象,而是添加到上下文中的Map集合作为变量,所以我们在没有#的情况下访问它们。 在某种程度上,它们作为命名空间。

 

param:用于获取请求参数。 $ {param.foo}是一个带有foo请求参数值的String [],所以$ {param.foo [0]}通常用于获取第一个值。

 

${param.foo}     // Retrieves a String[] with the values of request parameter 'foo'

${param.size()}

${param.isEmpty()}

${param.containsKey('foo')}

...

session:用于获取session属性。

${session.foo}

...

application:用于获取应用程序或servlet上下文属性。

${application.foo}

...

 

 

 

 

 

工具表达式对象

除了这些基本的对象之外,Thymeleaf将为我们提供一组工具对象,这些对象将帮助我们在表达式中执行常见任务。

#execInfo:有关正在处理的模板的信息。

#messages:用于在变量表达式中获取外部化消息的方法,与使用

#{...}语法获得的方式相同,操作消息的工具。

#uris:转义URL / URI部分的方法

#conversions:执行配置的转换服务(如果有的话)的方法。

#dates:java.util.Date对象的方法:格式化,组件提取等

#calendars:类似于#dates,但对于java.util.Calendar对象。

#numbers:用于格式化数字对象的方法。

#strings:String对象的⽅法:contains,startsWith,prepending /appending等

#objects:一般对象的方法,参照java.lang.Object;

#bools:判断布尔类型工具。

#arrays:数组操作的工具;

#lists:列表操作的工具,参照java.util.List;

#sets:Set操作工具,参照java.util.Set;

#maps:Map操作工具,参照java.util.Map;

#aggregates:操作数组或集合的工具;

#ids:处理可能重复的id属性的方法(例如,作为迭代的结果)。

 

 

例子:

简单数据转换(数字,日期)

<dt>价格</dt>

<dd th:text="${#numbers.formatDecimal(product.price, 1, 2)}">180</dd>

<dt>进货日期</dt>

<dd th:text="${#dates.format(product.availableFrom, 'yyyy-MM-dd')}">2014-12-01</dd>

字符串拼接

<dd th:text="${'$'+product.price}">235</dd>

 

 

原文:https://blog.csdn.net/malimingwq/article/details/79329921

 

 

 

五.其他

验证模板的正确性

<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-4.dtd">

<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-transitional-thymeleaf-4.dtd">

<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-frameset-thymeleaf-4.dtd">

<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml11-thymeleaf-4.dtd">

 

静态资源引入问题

可直接在static文件夹下的css文件夹和js文件夹引用

<link th:href="@{/css/style.css}"  rel="stylesheet" />

<script th:src="@{/js/jquery-2.1.4.min.js}"></script>

也可以设置一个前缀

spring:

  mvc:

    static-path-pattern: /static/**

 

引用:

<link th:href="@{/static/css/style.css}"  rel="stylesheet" />

<script th:src="@{/static/js/jquery-2.1.4.min.js}"></script>

 

 

 

 

 

结语

thymeleaf 对前端来讲确实是个好东西,前后端协作更方便,但是貌似如果改成完全的前后分离的模式,这些模板引擎就都用不到了,前端就是原生html+css+js,异步请求后端数据填充页面。完全的前后分离,总感觉这样做会更频繁的http请求后台,也有不太好的地方,Thymeleaf 反而是折中的方案了。从半分离到完全分离过渡。依产品而定吧,有些业务不适合分离。

 

 

 

猜你喜欢

转载自blog.csdn.net/qq877507054/article/details/84236224