Thymeleaf 是一款用于渲染 XML/XHTML/HTML5 内容的模板引擎。它与 JSP,Velocity,FreeMaker 等模板引擎类似,也可以轻易地与 Spring MVC 等 Web 框架集成。与其它模板引擎相比,Thymeleaf 最大的特点是,即使不启动 Web 应用,也可以直接在浏览器中打开并正确显示模板页面 。
目录
一、整合Thymeleaf
二、Thymeleaf 使用教程
三、Thymeleaf 实战应用
1、引入Thymeleaf starter依赖
org.springframework.boot spring-boot-starter-thymeleaf
2、在 application.properties 添加 Thymeleaf 相关配置
server.port= 8092#关闭 Thymeleaf 的缓存开发过程中无需重启
spring.thymeleaf.cache = false
#设置thymeleaf页面的编码
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.mode=HTML5
#设置thymeleaf页面的后缀
spring.thymeleaf.suffix=.html
#设置thymeleaf页面的存储路径
spring.thymeleaf.prefix=classpath:/templates/
Thymeleaf默认会开启页面缓存,提高页面并发能力。但会导致我们修改页面不会立即被展现,因此我们关闭缓存:spring.thymeleaf.cache=false
修改完毕页面,需要使用快捷键:Ctrl + Shift + F9来刷新工程。
3、编写访问 Thymeleaf 页面 Controller
@Controller
@RequestMapping("/hello")
public class ThymeleafHelloWrodController {@RequestMapping({"/", "/index"})@ResponseBodypublic String index(Model model,String id) {model.addAttribute("msg", "welcome you!" + id);Map user = new HashMap<>();user.put("uid","11111");user.put("umc","testmc");user.put("etel","13550125501");model.addAttribute("user", user);return "index"; //返回的是index.html的页面 }@RequestMapping("/thymeleaf")public String helloThymeleaf(Model model){model.addAttribute("hello","hello Thymeleaf!");return "hello/index";}
}
后台springmvc 使用 Model 传入数据
Thymeleaf的主要作用是把model中的数据渲染到html中,因此其语法主要是如何解析model中的数据。
3、Controller类编写(@RequestBody注解是必须加上的,将java对象转为json格式的数据。如果出现页面显示不了又没有报错可能就是Controller类没有加@RequestBody)
返回的是Thymeleaf 模板对应的index.html的页面
4、Thymeleaf 页面代码如下
src/main/resources/templates/index.html
首页
test p
p:[(${msg})]
5、访问页面
http://localhost:8092/index
http://localhost:8092/index?id=test
Thymeleaf 模板引擎具有以下特点:
动静结合:Thymeleaf 既可以直接使用浏览器打开,查看页面的静态效果,也可以通过 Web 应用程序进行访问,查看动态页面效果。
开箱即用:Thymeleaf 提供了 Spring 标准方言以及一个与 SpringMVC 完美集成的可选模块,可以快速的实现表单绑定、属性编辑器、国际化等功能。
多方言支持:它提供了 Thymeleaf 标准和 Spring 标准两种方言,可以直接套用模板实现 JSTL、 OGNL 表达式;必要时,开发人员也可以扩展和创建自定义的方言。
与 SpringBoot 完美整合:SpringBoot 为 Thymeleaf 提供了的默认配置,并且还为 Thymeleaf 设置了视图解析器,因此 Thymeleaf 可以与 Spring Boot 完美整合。
1、在页面的 html 标签中声明名称空间
在 html 标签中声明此名称空间,可避免编辑器出现 html 验证错误,但这一步并非必须进行的,即使我们不声明该命名空间,也不影响 Thymeleaf 的使用。
把html 的名称空间,改成:xmlns:th="http://www.thymeleaf.org" 会有语法提示
2、标准表达式语法
Thymeleaf的主要作用是把model中的数据渲染到html中,因此其语法主要是如何解析model中的数据。通过${}来获取model中的变量,注意这不是el表达式,而是ognl表达式,但是语法非常像。
Thymeleaf崇尚自然模板,意思就是模板是纯正的html代码,脱离模板引擎,在纯静态环境也可以直接运行。现在如果我们直接在html中编写 ${}这样的表达式,显然在静态环境下就会出错,这不符合Thymeleaf的理念。
欢迎您:请登录
静态情况下,th指令不会被识别,而是显示默认值:请登录
但是浏览器也不会报错,把它当做一个普通属性处理。这样span的默认值请登录就会展现在页面
如果是在Thymeleaf环境下,th指令就会被识别和解析,而th:text的含义就是替换所在标签中的文本内容,于是user.name的值就替代了 span中默认的请登录如果不支持这种th:的命名空间写法,那么可以把th:text换成 data-th-text,Thymeleaf也可以兼容。
th:text指令出于安全考虑,会把表达式读取到的值进行处理,防止html的注入。
例如,
你好
将会被格式化输出为$lt;p$gt;你好$lt;/p$lt;。如果想要不进行格式化输出,而是要输出原始内容,则使用th:utext来代替.
Thymeleaf中所有的表达式都需要写在指令中,指令是HTML5中的自定义属性,在Thymeleaf中所有指令都是以th:开头。因为表达式${user.name}是写在自定义属性中,因此在静态环境下,表达式的内容会被当做是普通字符串,浏览器会自动忽略这些指令,这样就不会报错了!
Name: Jack.
Age: 21.
friend: Rose.
对象.属性名方式
${user.name} 可以写作${user['name']}
Name: Jack.
Age: 21.
friend: Rose.
当数据量比较多的时候,频繁的写user.就会非常麻烦。
首先在 h2上 用 th:object="${user}"获取user的值,并且保存
然后,在h2内部的任意元素上,可以通过 *{属性名}的方式,来获取user中的属性,这样就省去了大量的user.前缀了
FirstName: Jack.
LastName: Li.
ognl表达式本身就支持方法调用
Thymeleaf中提供了一些内置对象,并且在这些对象中提供了一些方法,方便我们来调用。获取这些对象,需要使用#对象名来引用。
一些环境相关对象
对象 作用
#ctx 获取Thymeleaf自己的Context对象
#requset 如果是web程序,可以获取HttpServletRequest对象
#response 如果是web程序,可以获取HttpServletReponse对象
#session 如果是web程序,可以获取HttpSession对象
#servletContext 如果是web程序,可以获取HttpServletContext对象
Thymeleaf提供的全局对象:
对象 作用
#dates 处理java.util.date的工具对象
#calendars 处理java.util.calendar的工具对象
#numbers 用来对数字格式化的方法
#strings 用来处理字符串的方法
#bools 用来判断布尔值的方法
#arrays 用来护理数组的方法
#lists 用来处理List集合的方法
#sets 用来处理set集合的方法
#maps 用来处理map集合的方法
java代码:
@GetMapping("show3")
public String show3(Model model){model.addAttribute("today", new Date());return "show3";
}
页面代码:
今天是: 2018-04-25
${#strings.equals('编程帮',name)}${#session.getAttribute('map')}
${session.map}
字面值:
基本类型如:字符串、数值、布尔等,并不希望被Thymeleaf解析为变量,这个时候称为字面值
字符串字面值:th:text="'thymeleaf'" 使用一对'引用的内容
数字字面值:th:text="2018" 数字不需要任何特殊语法, 写的什么就是什么,而且可以直接进行算术运算
布尔字面值:th:if="true"
空字面值:
你正在观看 template 的字符串常量值.
拼接
我们经常会用到普通字符串与表达式拼接的情况:
字符串字面值需要用'',拼接起来非常麻烦,Thymeleaf对此进行了简化,使用一对|即可:
运算
支持的算术运算符:+ - * / %
支持的比较运算:>, <, >= and <=
但是>, <不能直接使用,因为xml会解析为标签,要使用别名。
注意 == and !=不仅可以比较数值,类似于equals的功能。
可以使用的别名:gt (>), lt (<), ge (>=), le (<=), not (!). Also eq (==), neq/ne (!=).
三元运算:
默认值: ( ?:之间没有空格 )
${}内部的是通过OGNL表达式引擎解析的,外部的才是通过Thymeleaf的引擎解析,因此运算符尽量放在${}外进行。
在 Thymeleaf 模板文件中,你可以使用
th:*
(或者使用th:attr
属性)来设置任意的 HTML5 标签属性的值。不仅如此,你还可以th:*-*
来同时为多个不同的标签属性设置相同的一个值,甚至你可以使用th:attrappend
和th:attrprepend
来追加新的值到现有的标签属性值中。th:attr 这种方式是不被推荐的
Welcome to BeiJing!![]()
th:*
中的*
可以是 HTML5 支持的任意属性名称,甚至这些属性名称可以是自定义的
th:*-*
如果想要同时为标签的多个不同属性设置相同的一个值,可以使用th:*-*
的语法:th:attrappend & th:attrprepend 可以将表达式的结果分别追加到指定的属性值之后和之前。
还有两个常用的具体附加属性
th:classappend="..."
和th:styleappend=""
。它们分别用来代替th:attrappend="class=..."
和th:attrappend="style=..."
循环/IF/SWITCH
Onions 2.41
Onions 2.41
stat对象包含以下属性:
index,从0开始的角标
count,元素的个数,从1开始
size,总元素个数
current,当前遍历到的元素
even/odd,返回是否为奇偶,boolean值
first/last,返回是否为第一或最后,boolean值
用户是管理员
用户是经理
用户是别的玩意
JS模板
在script标签中通过th:inline="javascript"来声明这是要特殊处理的js脚本
语法结构:
const user = /*[[Thymeleaf表达式]]*/ "静态环境下的默认值";
因为Thymeleaf被注释起来,因此即便是静态环境下, js代码也不会报错,而是采用表达式后面跟着的默认值。
链接表达式 @{}
@{}
是专门用来处理 URL 链接地址的。
不管是静态资源的引用,还是 form 表单的请求,凡是链接都可以用链接表达式 (@{...})。链接表达式的形式结构如下:
无参请求:@{/xxx}
有参请求:@{/xxx(k1=v1,k2=v2)}
绝对地址:
页面相对地址示例:
上下文相对地址(相对于当前的服务)示例:
服务器相对地址(相对于部署在同一个服务器中的不同服务)示例:
参数使用示例:
片段表达式
~{}
可以用来引用一段公共的 HTML 代码片段。
在 Thymeleaf 模板文件中,你可以使用
th:fragment
属性来定义一段公共的代码片段,然后你可以通过使用th:insert
、th:replace
属性来将这些公共的代码片段引入到模板文件中来。
th:insert
是直接将代码片段插入到标签体内
th:replace
则是用代码片段直接替换标签体内容。
src/main/resources/templates/base.html,通过th:fragment
属性定义一段公共的代码片段:
© 2017 fanlychie
src/main/resources/templates/index.html,通过th:insert
属性引用一段公共的代码片段:
(1)其中,
~{}
是可选的,我们可以去掉这层的包裹:
(2)若 index.html 与 base.html 不在同级目录,如 templates/commons/base.html:
(3)使用th:fragment属性定义代码片段时,你还可以声明一组参数:
1、input 、textarea 赋值
//JAVA
@RequestMapping(value = { "formData", "" })
public String list(HttpServletRequest request, ModelMap model) {Entity entity = xxxService.getEntity();model.addAttribute("entity", entity);return "test.html";
}
2.复选框 判断选中
//JAVA
@RequestMapping(value = { "checkboxValue", "" })
public String list(HttpServletRequest request, ModelMap model) {Entity entity = xxxService.getEntity();model.addAttribute("entity", entity);return "test.html";
}
aaa
bbb
3.下拉框 动态赋值 与 回显
//JAVA
@RequestMapping(value = { "selectList", "" })
public String list(HttpServletRequest request, ModelMap model) {List selectList = xxxService.getSelectList();int type = xxxService.getType();model.addAttribute("type", type);model.addAttribute("selectList", selectList);return "test.html";
}
4.循环遍历
@RequestMapping(value = { "loopTest", "" })
public String list(HttpServletRequest request, ModelMap model) {List dataList = xxxService.getEntityList();Map> dataMap = xxxService.getEntityMap();model.addAttribute("dataList", dataList);model.addAttribute("dataMap", dataMap);return "test.html";
}
ID 名称 类型 时间 是否可用 字符型整型日期
[[${dataEntry.key}]] [[${data.id}]]: [[${data.name}]]
@RequestMapping(value = { "formData", "" })
public String list(HttpServletRequest request, ModelMap model) {Entity entity = xxxService.getEntity();model.addAttribute("entity", entity);return "test.html";
}
超链接1
超链接2