摘要:(then) : (else)这种语法来判断显示的内容\u003C\u002Fp\u003E\u003Cp\u003E\u003Cstrong\u003E3、for 循环\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cpre\u003E

\u003Cbr\u003E 1\u003Cbr\u003E \u003Cbr\u003E \u003Cbr\u003E \u003Cbr\u003E Mark\u003Cbr\u003E Otto\u003Cbr\u003E @mdo\u003Cbr\u003E index\u003Cbr\u003E\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Cp\u003EiterStat称作状态变量,属性有:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003Eindex:当前迭代对象的 index(从0开始计算)\u003C\u002Fli\u003E\u003Cli\u003Ecount: 当前迭代对象的 index(从1开始计算)\u003C\u002Fli\u003E\u003Cli\u003Esize:被迭代对象的大小\u003C\u002Fli\u003E\u003Cli\u003Ecurrent:当前迭代变量\u003C\u002Fli\u003E\u003Cli\u003Eeven\u002Fodd:布尔值,当前循环是否是偶数\u002F奇数(从0开始计算)\u003C\u002Fli\u003E\u003Cli\u003Efirst:布尔值,当前循环是否是第一个\u003C\u002Fli\u003E\u003Cli\u003Elast:布尔值,当前循环是否是最后一个\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E\u003Cstrong\u003E4、URL\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cp\u003EURL 在 Web 应用模板中占据着十分重要的地位,需要特别注意的是 Thymeleaf 对于 URL 的处理是通过语法 @{...}来处理的。'img\u002Ffavicon.png' : ${collect.webLogo})} + ')'\" >\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Cp\u003E几点说明:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E上例中 URL 最后的(orderId=${o.id}) 表示将括号内的内容作为 URL 参数处理,该语法避免使用字符串拼接,大大提高了可读性\u003C\u002Fli\u003E\u003Cli\u003E@{...}表达式中可以通过{orderId}访问 Context 中的 orderId 变量\u003C\u002Fli\u003E\u003Cli\u003E@{\u002Forder}是 Context 相关的相对路径,在渲染时会自动添加上当前 Web 应用的 Context 名字,假设 context 名字为 app,那么结果应该是 \u002Fapp\u002Forder\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E\u003Cstrong\u003E5、内联 js\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cp\u003E内联文本:[[。"\u003Cdiv\u003E\u003Cdiv class=\"pgc-img\"\u003E\u003Cimg src=\"http:\u002F\u002Fp1.pstatp.com\u002Flarge\u002Fpgc-image\u002F2c2bdb8cd80d486d9b345357e45bbc0b\" img_width=\"640\" img_height=\"274\" alt=\"Spring Boot 系列:新一代的模板引擎Thymeleaf 使用详解\" inline=\"0\"\u003E\u003Cp class=\"pgc-img-caption\"\u003E\u003C\u002Fp\u003E\u003C\u002Fdiv\u003E\u003Cp\u003EThymeleaf 是新一代的模板引擎,在 Spring4.0 中推荐使用 Thymeleaf 来做前端模版引擎。\u003C\u002Fp\u003E\u003Ch1\u003EThymeleaf 介绍\u003C\u002Fh1\u003E\u003Cp\u003E简单说,Thymeleaf 是一个跟 Velocity、FreeMarker 类似的模板引擎,它可以完全替代 JSP 。相较与其他的模板引擎,它有如下三个极吸引人的特点:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E1.Thymeleaf 在有网络和无网络的环境下皆可运行,即它可以让美工在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数据的动态页面效果。这是由于它支持 html 原型,然后在 html 标签里增加额外的属性来达到模板+数据的展示方式。浏览器解释 html 时会忽略未定义的标签属性,所以 Thymeleaf 的模板可以静态地运行;当有数据返回到页面时,Thymeleaf 标签会动态地替换掉静态内容,使页面动态显示。\u003C\u002Fli\u003E\u003Cli\u003E2.Thymeleaf 开箱即用的特性。它提供标准和 Spring 标准两种方言,可以直接套用模板实现 JSTL、 OGNL表达式效果,避免每天套模板、改 Jstl、改标签的困扰。同时开发人员也可以扩展和创建自定义的方言。\u003C\u002Fli\u003E\u003Cli\u003E3.Thymeleaf 提供 Spring 标准方言和一个与 SpringMVC 完美集成的可选模块,可以快速的实现表单绑定、属性编辑器、国际化等功能。\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Ch1\u003E标准表达式语法\u003C\u002Fh1\u003E\u003Cp\u003E它们分为四类:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E1.变量表达式\u003C\u002Fli\u003E\u003Cli\u003E2.选择或星号表达式\u003C\u002Fli\u003E\u003Cli\u003E3.文字国际化表达式\u003C\u002Fli\u003E\u003Cli\u003E4.URL 表达式\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Ch1\u003E变量表达式\u003C\u002Fh1\u003E\u003Cp\u003E变量表达式即 OGNL 表达式或 Spring EL 表达式(在 Spring 术语中也叫 model attributes)。如下所示:\u003C\u002Fp\u003E\u003Cp\u003E${session.user.name}\u003C\u002Fp\u003E\u003Cp\u003E它们将以HTML标签的一个属性来表示:\u003C\u002Fp\u003E\u003Cpre\u003E<span th:text=\"${book.author.name}\"> \u003Cbr\u003E<li th:each=\"book : ${books}\"> \u003Cbr\u003E\u003C\u002Fpre\u003E\u003Cp\u003E选择(星号)表达式\u003C\u002Fp\u003E\u003Cp\u003E选择表达式很像变量表达式,不过它们用一个预先选择的对象来代替上下文变量容器(map)来执行,如下:\u003C\u002Fp\u003E\u003Cp\u003E*{customer.name}\u003C\u002Fp\u003E\u003Cp\u003E被指定的 object 由 th:object 属性定义:\u003C\u002Fp\u003E\u003Cpre\u003E<div th:object=\"${book}\"> \u003Cbr\u003E ... \u003Cbr\u003E <span th:text=\"*{title}\">...<\u002Fspan> \u003Cbr\u003E ... \u003Cbr\u003E<\u002Fdiv> \u003Cbr\u003E\u003C\u002Fpre\u003E\u003Ch1\u003E文字国际化表达式\u003C\u002Fh1\u003E\u003Cp\u003E文字国际化表达式允许我们从一个外部文件获取区域文字信息(.properties),用 Key 索引 Value,还可以提供一组参数(可选).\u003C\u002Fp\u003E\u003Cpre\u003E#{main.title} \u003Cbr\u003E#{message.entrycreated(${entryId})} \u003Cbr\u003E\u003C\u002Fpre\u003E\u003Cp\u003E可以在模板文件中找到这样的表达式代码:\u003C\u002Fp\u003E\u003Cpre\u003E<table> \u003Cbr\u003E ... \u003Cbr\u003E <th th:text=\"#{header.address.city}\">...<\u002Fth> \u003Cbr\u003E <th th:text=\"#{header.address.country}\">...<\u002Fth> \u003Cbr\u003E ... \u003Cbr\u003E<\u002Ftable> \u003Cbr\u003E\u003C\u002Fpre\u003E\u003Ch1\u003EURL 表达式\u003C\u002Fh1\u003E\u003Cp\u003EURL 表达式指的是把一个有用的上下文或回话信息添加到 URL,这个过程经常被叫做 URL 重写。 \u003C\u002Fp\u003E\u003Cp\u003E@{\u002Forder\u002Flist}\u003C\u002Fp\u003E\u003Cp\u003EURL还可以设置参数: \u003C\u002Fp\u003E\u003Cp\u003E@{\u002Forder\u002Fdetails(id=${orderId})}\u003C\u002Fp\u003E\u003Cp\u003E相对路径: \u003C\u002Fp\u003E\u003Cp\u003E@{..\u002Fdocuments\u002Freport}\u003C\u002Fp\u003E\u003Cp\u003E让我们看这些表达式:\u003C\u002Fp\u003E\u003Cpre\u003E<form th:action=\"@{\u002FcreateOrder}\"> \u003Cbr\u003E<a href=\"main.html\" th:href=\"@{\u002Fmain}\">\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Cp\u003E变量表达式和星号表达有什么区别吗?\u003C\u002Fp\u003E\u003Cp\u003E如果不考虑上下文的情况下,两者没有区别;星号语法评估在选定对象上表达,而不是整个上下文 \u003C\u002Fp\u003E\u003Cp\u003E什么是选定对象?就是父标签的值,如下:\u003C\u002Fp\u003E\u003Cpre\u003E<div th:object=\"${session.user}\">\u003Cbr\u003E <p>Name: <span th:text=\"*{firstName}\">Sebastian<\u002Fspan>.<\u002Fp>\u003Cbr\u003E <p>Surname: <span th:text=\"*{lastName}\">Pepper<\u002Fspan>.<\u002Fp>\u003Cbr\u003E <p>Nationality: <span th:text=\"*{nationality}\">Saturn<\u002Fspan>.<\u002Fp>\u003Cbr\u003E<\u002Fdiv>\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Cp\u003E这是完全等价于:\u003C\u002Fp\u003E\u003Cpre\u003E<div th:object=\"${session.user}\">\u003Cbr\u003E <p>Name: <span th:text=\"${session.user.firstName}\">Sebastian<\u002Fspan>.<\u002Fp>\u003Cbr\u003E <p>Surname: <span th:text=\"${session.user.lastName}\">Pepper<\u002Fspan>.<\u002Fp>\u003Cbr\u003E <p>Nationality: <span th:text=\"${session.user.nationality}\">Saturn<\u002Fspan>.<\u002Fp>\u003Cbr\u003E<\u002Fdiv>\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Cp\u003E当然,美元符号和星号语法可以混合使用:\u003C\u002Fp\u003E\u003Cpre\u003E <div th:object=\"${session.user}\">\u003Cbr\u003E\t <p>Name: <span th:text=\"*{firstName}\">Sebastian<\u002Fspan>.<\u002Fp>\u003Cbr\u003E \t <p>Surname: <span th:text=\"${session.user.lastName}\">Pepper<\u002Fspan>.<\u002Fp>\u003Cbr\u003E <p>Nationality: <span th:text=\"*{nationality}\">Saturn<\u002Fspan>.<\u002Fp>\u003Cbr\u003E <\u002Fdiv>\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Ch1\u003E表达式支持的语法\u003C\u002Fh1\u003E\u003Cp\u003E\u003Cstrong\u003E字面(Literals)\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E文本文字(Text literals): 'one text', 'Another one!',…\u003C\u002Fli\u003E\u003Cli\u003E数字文本(Number literals): 0, 34, 3.0, 12.3,…\u003C\u002Fli\u003E\u003Cli\u003E布尔文本(Boolean literals):true, false\u003C\u002Fli\u003E\u003Cli\u003E空(Null literal):null\u003C\u002Fli\u003E\u003Cli\u003E文字标记(Literal tokens):one, sometext, main,…\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E\u003Cstrong\u003E文本操作(Text operations)\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E字符串连接(String concatenation):+\u003C\u002Fli\u003E\u003Cli\u003E文本替换(Literal substitutions):|The name is ${name}|\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E\u003Cstrong\u003E算术运算(Arithmetic operations)\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E二元运算符(Binary operators):+, -, *, \u002F, %\u003C\u002Fli\u003E\u003Cli\u003E减号(单目运算符)Minus sign (unary operator):-\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E\u003Cstrong\u003E布尔操作(Boolean operations)\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E二元运算符(Binary operators):and, or\u003C\u002Fli\u003E\u003Cli\u003E布尔否定(一元运算符)Boolean negation (unary operator):!, not\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E\u003Cstrong\u003E比较和等价(Comparisons and equality)\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E比较(Comparators):>, <, >=, <= (gt, lt, ge, le)\u003C\u002Fli\u003E\u003Cli\u003E等值运算符(Equality operators):==, != (eq, ne)\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E\u003Cstrong\u003E条件运算符(Conditional operators)\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003EIf-then:(if) ? (then)\u003C\u002Fli\u003E\u003Cli\u003EIf-then-else:(if) ? (then) : (else)\u003C\u002Fli\u003E\u003Cli\u003EDefault: (value) ?:(defaultvalue)\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E所有这些特征可以被组合并嵌套:\u003C\u002Fp\u003E\u003Cpre\u003E'User is of type ' + (${user.isAdmin()} ? 'Administrator' : (${user.type} ?: 'Unknown'))\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Ch1\u003E常用th标签都有那些?\u003C\u002Fh1\u003E\u003Cdiv class=\"pgc-img\"\u003E\u003Cimg src=\"http:\u002F\u002Fp1.pstatp.com\u002Flarge\u002Fpgc-image\u002F1380fdc3410d41949e7b2acfb8c663f6\" img_width=\"1085\" img_height=\"696\" alt=\"Spring Boot 系列:新一代的模板引擎Thymeleaf 使用详解\" inline=\"0\"\u003E\u003Cp class=\"pgc-img-caption\"\u003E\u003C\u002Fp\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"pgc-img\"\u003E\u003Cimg src=\"http:\u002F\u002Fp9.pstatp.com\u002Flarge\u002Fpgc-image\u002F05484c2ca1ec42fcb708ef34297a24e2\" img_width=\"1078\" img_height=\"867\" alt=\"Spring Boot 系列:新一代的模板引擎Thymeleaf 使用详解\" inline=\"0\"\u003E\u003Cp class=\"pgc-img-caption\"\u003E\u003C\u002Fp\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E还有非常多的标签,这里只列出最常用的几个,由于一个标签内可以包含多个th:x属性,其生效的优先级顺序为:include,each,if\u002Funless\u002Fswitch\u002Fcase,with,attr\u002Fattrprepend\u002Fattrappend,value\u002Fhref,src ,etc,text\u002Futext,fragment,remove。 \u003C\u002Fp\u003E\u003Ch1\u003E几种常用的使用方法\u003C\u002Fh1\u003E\u003Cp\u003E\u003Cstrong\u003E1、赋值、字符串拼接\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cpre\u003E<p th:text=\"${collect.description}\">description<\u002Fp>\u003Cbr\u003E<span th:text=\"'Welcome to our application, ' + ${user.name} + '!'\">\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Cp\u003E字符串拼接还有另外一种简洁的写法\u003C\u002Fp\u003E\u003Cpre\u003E<span th:text=\"|Welcome to our application, ${user.name}!|\">\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Cp\u003E\u003Cstrong\u003E2、条件判断 If\u002FUnless\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cp\u003EThymeleaf中使用th:if和th:unless属性进行条件判断,下面的例子中,<a>标签只有在th:if中条件成立时才显示:\u003C\u002Fp\u003E\u003Cpre\u003E<a th:if=\"${myself=='yes'}\" > <\u002Fi> <\u002Fa>\u003Cbr\u003E<a th:unless=${session.user != null} th:href=\"@{\u002Flogin}\" >Login<\u002Fa>\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Cp\u003Eth:unless 于 th:if 恰好相反,只有表达式中的条件不成立,才会显示其内容。\u003C\u002Fp\u003E\u003Cp\u003E也可以使用 (if) ? (then) : (else)这种语法来判断显示的内容\u003C\u002Fp\u003E\u003Cp\u003E\u003Cstrong\u003E3、for 循环\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cpre\u003E<tr th:each=\"collect,iterStat : ${collects}\"> \u003Cbr\u003E <th scope=\"row\" th:text=\"${collect.id}\">1<\u002Fth>\u003Cbr\u003E <td >\u003Cbr\u003E <img th:src=\"${collect.webLogo}\"\u002F>\u003Cbr\u003E <\u002Ftd>\u003Cbr\u003E <td th:text=\"${collect.url}\">Mark<\u002Ftd>\u003Cbr\u003E <td th:text=\"${collect.title}\">Otto<\u002Ftd>\u003Cbr\u003E <td th:text=\"${collect.description}\">@mdo<\u002Ftd>\u003Cbr\u003E <td th:text=\"${terStat.index}\">index<\u002Ftd>\u003Cbr\u003E<\u002Ftr>\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Cp\u003EiterStat称作状态变量,属性有:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003Eindex:当前迭代对象的 index(从0开始计算)\u003C\u002Fli\u003E\u003Cli\u003Ecount: 当前迭代对象的 index(从1开始计算)\u003C\u002Fli\u003E\u003Cli\u003Esize:被迭代对象的大小\u003C\u002Fli\u003E\u003Cli\u003Ecurrent:当前迭代变量\u003C\u002Fli\u003E\u003Cli\u003Eeven\u002Fodd:布尔值,当前循环是否是偶数\u002F奇数(从0开始计算)\u003C\u002Fli\u003E\u003Cli\u003Efirst:布尔值,当前循环是否是第一个\u003C\u002Fli\u003E\u003Cli\u003Elast:布尔值,当前循环是否是最后一个\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E\u003Cstrong\u003E4、URL\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cp\u003EURL 在 Web 应用模板中占据着十分重要的地位,需要特别注意的是 Thymeleaf 对于 URL 的处理是通过语法 @{...}来处理的。 如果需要 Thymeleaf 对 URL 进行渲染,那么务必使用 th:href,th:src 等属性,下面是一个例子\u003C\u002Fp\u003E\u003Cpre\u003E<!-- Will produce 'http:\u002F\u002Flocalhost:8080\u002Fstandard\u002Funread' (plus rewriting) -->\u003Cbr\u003E <a th:href=\"@{\u002Fstandard\u002F{type}(type=${type})}\">view<\u002Fa>\u003Cbr\u003E<!-- Will produce '\u002Fgtvg\u002Forder\u002F3\u002Fdetails' (plus rewriting) -->\u003Cbr\u003E<a href=\"details.html\" th:href=\"@{\u002Forder\u002F{orderId}\u002Fdetails(orderId=${o.id})}\">view<\u002Fa>\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Cp\u003E设置背景\u003C\u002Fp\u003E\u003Cpre\u003E<div th:style=\"'background:url(' + @{\u002F<path-to-image>} + ');'\"><\u002Fdiv>\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Cp\u003E根据属性值改变背景\u003C\u002Fp\u003E\u003Cpre\u003E <div class=\"media-object resource-card-image\" th:style=\"'background:url(' + @{(${collect.webLogo}=='' ? 'img\u002Ffavicon.png' : ${collect.webLogo})} + ')'\" ><\u002Fdiv>\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Cp\u003E几点说明:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E上例中 URL 最后的(orderId=${o.id}) 表示将括号内的内容作为 URL 参数处理,该语法避免使用字符串拼接,大大提高了可读性\u003C\u002Fli\u003E\u003Cli\u003E@{...}表达式中可以通过{orderId}访问 Context 中的 orderId 变量\u003C\u002Fli\u003E\u003Cli\u003E@{\u002Forder}是 Context 相关的相对路径,在渲染时会自动添加上当前 Web 应用的 Context 名字,假设 context 名字为 app,那么结果应该是 \u002Fapp\u002Forder\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E\u003Cstrong\u003E5、内联 js\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cp\u003E内联文本:[[…]] 内联文本的表示方式,使用时,必须先用th:inline=\"text\u002Fjavascript\u002Fnone\"激活,th:inline可以在父级标签内使用,甚至作为 body 的标签。内联文本尽管比th:text的代码少,不利于原型显示。\u003C\u002Fp\u003E\u003Cpre\u003E<script th:inline=\"javascript\">\u003Cbr\u003E\u002F*<![CDATA[*\u002F\u003Cbr\u003E...\u003Cbr\u003Evar username = \u002F*[[${sesion.user.name}]]*\u002F 'Sebastian';\u003Cbr\u003Evar size = \u002F*[[${size}]]*\u002F 0;\u003Cbr\u003E...\u003Cbr\u003E\u002F*]]>*\u002F\u003Cbr\u003E<\u002Fscript>\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Cp\u003Ejs 附加代码:\u003C\u002Fp\u003E\u003Cpre\u003E\u002F*[+\u003Cbr\u003Evar msg = 'This is a working application';\u003Cbr\u003E+]*\u002F\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Cp\u003Ejs 移除代码:\u003C\u002Fp\u003E\u003Cpre\u003E\u002F*[- *\u002F\u003Cbr\u003Evar msg = 'This is a non-working template';\u003Cbr\u003E\u002F* -]*\u002F\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Cp\u003E\u003Cstrong\u003E6、内嵌变量\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cp\u003E为了模板更加易用,Thymeleaf 还提供了一系列 Utility 对象(内置于 Context 中),可以通过 # 直接访问:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003Edates : \u003Cem\u003Ejava.util.Date的功能方法类。\u003C\u002Fem\u003E\u003C\u002Fli\u003E\u003Cli\u003Ecalendars : \u003Cem\u003E类似#dates,面向java.util.Calendar\u003C\u002Fem\u003E\u003C\u002Fli\u003E\u003Cli\u003Enumbers : \u003Cem\u003E格式化数字的功能方法类\u003C\u002Fem\u003E\u003C\u002Fli\u003E\u003Cli\u003Estrings : \u003Cem\u003E字符串对象的功能类,contains,startWiths,prepending\u002Fappending等等。\u003C\u002Fem\u003E\u003C\u002Fli\u003E\u003Cli\u003Eobjects: \u003Cem\u003E对objects的功能类操作。\u003C\u002Fem\u003E\u003C\u002Fli\u003E\u003Cli\u003Ebools: \u003Cem\u003E对布尔值求值的功能方法。\u003C\u002Fem\u003E\u003C\u002Fli\u003E\u003Cli\u003Earrays:\u003Cem\u003E对数组的功能类方法。\u003C\u002Fem\u003E\u003C\u002Fli\u003E\u003Cli\u003Elists: \u003Cem\u003E对lists功能类方法\u003C\u002Fem\u003E\u003C\u002Fli\u003E\u003Cli\u003Esets\u003C\u002Fli\u003E\u003Cli\u003Emaps\u003C\u002Fli\u003E\u003Cli\u003E…\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E下面用一段代码来举例一些常用的方法:\u003C\u002Fp\u003E\u003Cp\u003Edates\u003C\u002Fp\u003E\u003Cpre\u003E\u002F*\u003Cbr\u003E * Format date with the specified pattern\u003Cbr\u003E * Also works with arrays, lists or sets\u003Cbr\u003E *\u002F\u003Cbr\u003E${#dates.format(date, 'dd\u002FMMM\u002Fyyyy HH:mm')}\u003Cbr\u003E${#dates.arrayFormat(datesArray, 'dd\u002FMMM\u002Fyyyy HH:mm')}\u003Cbr\u003E${#dates.listFormat(datesList, 'dd\u002FMMM\u002Fyyyy HH:mm')}\u003Cbr\u003E${#dates.setFormat(datesSet, 'dd\u002FMMM\u002Fyyyy HH:mm')}\u003Cbr\u003E\u002F*\u003Cbr\u003E * Create a date (java.util.Date) object for the current date and time\u003Cbr\u003E *\u002F\u003Cbr\u003E${#dates.createNow()}\u003Cbr\u003E\u002F*\u003Cbr\u003E * Create a date (java.util.Date) object for the current date (time set to 00:00)\u003Cbr\u003E *\u002F\u003Cbr\u003E${#dates.createToday()}\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Cp\u003Estrings\u003C\u002Fp\u003E\u003Cpre\u003E\u002F*\u003Cbr\u003E * Check whether a String is empty (or null). Performs a trim() operation before check\u003Cbr\u003E * Also works with arrays, lists or sets\u003Cbr\u003E *\u002F\u003Cbr\u003E${#strings.isEmpty(name)}\u003Cbr\u003E${#strings.arrayIsEmpty(nameArr)}\u003Cbr\u003E${#strings.listIsEmpty(nameList)}\u003Cbr\u003E${#strings.setIsEmpty(nameSet)}\u003Cbr\u003E\u002F*\u003Cbr\u003E * Check whether a String starts or ends with a fragment\u003Cbr\u003E * Also works with arrays, lists or sets\u003Cbr\u003E *\u002F\u003Cbr\u003E${#strings.startsWith(name,'Don')} \u002F\u002F also array*, list* and set*\u003Cbr\u003E${#strings.endsWith(name,endingFragment)} \u002F\u002F also array*, list* and set*\u003Cbr\u003E\u002F*\u003Cbr\u003E * Compute length\u003Cbr\u003E * Also works with arrays, lists or sets\u003Cbr\u003E *\u002F\u003Cbr\u003E${#strings.length(str)}\u003Cbr\u003E\u002F*\u003Cbr\u003E * Null-safe comparison and concatenation\u003Cbr\u003E *\u002F\u003Cbr\u003E${#strings.equals(str)}\u003Cbr\u003E${#strings.equalsIgnoreCase(str)}\u003Cbr\u003E${#strings.concat(str)}\u003Cbr\u003E${#strings.concatReplaceNulls(str)}\u003Cbr\u003E\u002F*\u003Cbr\u003E * Random\u003Cbr\u003E *\u002F\u003Cbr\u003E${#strings.randomAlphanumeric(count)}\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Ch1\u003E使用 Thymeleaf 布局\u003C\u002Fh1\u003E\u003Cp\u003ESpring Boot 2.0 将布局单独提取了出来,需要单独引入依赖:thymeleaf-layout-dialect。\u003C\u002Fp\u003E\u003Cpre\u003E<dependency>\u003Cbr\u003E <groupId>org.springframework.boot<\u002FgroupId>\u003Cbr\u003E <artifactId>spring-boot-starter-thymeleaf<\u002FartifactId>\u003Cbr\u003E<\u002Fdependency>\u003Cbr\u003E<dependency>\u003Cbr\u003E <groupId>nz.net.ultraq.thymeleaf<\u002FgroupId>\u003Cbr\u003E <artifactId>thymeleaf-layout-dialect<\u002FartifactId>\u003Cbr\u003E<\u002Fdependency>\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Cp\u003E定义代码片段\u003C\u002Fp\u003E\u003Cpre\u003E<footer th:fragment=\"copy\"> \u003Cbr\u003E© 2019\u003Cbr\u003E<\u002Ffooter>\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Cp\u003E在页面任何地方引入:\u003C\u002Fp\u003E\u003Cpre\u003E<body>\u003Cbr\u003E <div th:insert=\"layout\u002Fcopyright :: copyright\"><\u002Fdiv>\u003Cbr\u003E <div th:replace=\"layout\u002Fcopyright :: copyright\"><\u002Fdiv>\u003Cbr\u003E<\u002Fbody>\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Cp\u003Eth:insert 和 th:replace 区别,insert 只是加载,replace 是替换。Thymeleaf 3.0 推荐使用 th:insert 替换 2.0 的 th:replace。\u003C\u002Fp\u003E\u003Cp\u003E返回的 HTML 如下:\u003C\u002Fp\u003E\u003Cpre\u003E<body> \u003Cbr\u003E <div> © 2019 <\u002Fdiv> \u003Cbr\u003E <footer>© 2019 <\u002Ffooter> \u003Cbr\u003E<\u002Fbody>\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Cp\u003E下面是一个常用的后台页面布局,将整个页面分为头部,尾部、菜单栏、隐藏栏,点击菜单只改变 content 区域的页面\u003C\u002Fp\u003E\u003Cpre\u003E<body class=\"layout-fixed\">\u003Cbr\u003E <div th:fragment=\"navbar\" class=\"wrapper\" role=\"navigation\">\u003Cbr\u003E\t<div th:replace=\"fragments\u002Fheader :: header\">Header<\u002Fdiv>\u003Cbr\u003E\t<div th:replace=\"fragments\u002Fleft :: left\">left<\u002Fdiv>\u003Cbr\u003E\t<div th:replace=\"fragments\u002Fsidebar :: sidebar\">sidebar<\u002Fdiv>\u003Cbr\u003E\t<div layout:fragment=\"content\" id=\"content\" ><\u002Fdiv>\u003Cbr\u003E\t<div th:replace=\"fragments\u002Ffooter :: footer\">footer<\u002Fdiv>\u003Cbr\u003E <\u002Fdiv>\u003Cbr\u003E<\u002Fbody>\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Cp\u003E任何页面想使用这样的布局值只需要替换中见的 content 模块即可\u003C\u002Fp\u003E\u003Cpre\u003E<html xmlns:th=\"http:\u002F\u002Fwww.thymeleaf.org\" layout:decorator=\"layout\">\u003Cbr\u003E <body>\u003Cbr\u003E <section layout:fragment=\"content\">\u003Cbr\u003E ...\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Cp\u003E也可以在引用模版的时候传参\u003C\u002Fp\u003E\u003Cpre\u003E<head th:include=\"layout :: htmlhead\" th:with=\"title='Hello'\"><\u002Fhead>\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Cp\u003Elayout 是文件地址,如果有文件夹可以这样写fileName\u002Flayout:htmlhead,htmlhead 是指定义的代码片段 如th:fragment=\"copy\"\u003C\u002Fp\u003E\u003C\u002Fdiv\u003E"'.slice(6, -6), groupId: '6719716348475212296
相关文章