在我们平时的开发中,用了很久的jsp作view显示层,但是标签库和JSP缺乏良好格式的一个副作用就是它很少能够与其产生的HTML类似。所以,在Web浏览器或HTML编辑器中查看未经渲染的JSP模板是非常令人困惑的,而且得到的结果看上去也非常丑陋(也就是不放到服务器,直接本地打开)。
但是Thymeleaf模板是原生的,不依赖于标签库。它能在接受原始HTML的地方进行编辑和渲染(也就是说我们通过thymeleaf写一个页面,如果不放到服务器进行渲染,也是可以看到效果的,跟后端打开基本相同)
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
配置springbean视图
首先我们需要让springboot(springmvc通用)知道我们的页面是通过什么来渲染的(jsp,freemarker,thymeleaf等等,以及模板的位置等信息)
/** * 设置视图解析器 * @param templateEngine * @return */ @Bean public ViewResolver viewResolver(SpringTemplateEngine templateEngine){ ThymeleafViewResolver resolver = new ThymeleafViewResolver(); resolver.setTemplateEngine(templateEngine); return resolver; } /** * 设置模板引擎 * @param templateResolver * @return */ @Bean public SpringTemplateEngine templateEngine(TemplateResolver templateResolver){ SpringTemplateEngine engine = new SpringTemplateEngine(); engine.setTemplateResolver(templateResolver); return engine; } /** * 模板解析引擎 * @return */ @Bean public TemplateResolver templateResolver(){ TemplateResolver resolver = new SpringResourceTemplateResolver(); resolver.setPrefix("/WEB-INF/template/");//设置地址前缀 resolver.setSuffix(".html");//设置后缀 resolver.setCacheable(false);//设置不缓存 resolver.setTemplateMode("HTML5"); return resolver; }
ThymeleafViewResolver是Spring MVC中ViewResolver的一个实现类。像其他的视图解析器一样,它会接受一个逻辑视图名称,并将其解析为视图
TemplateResolver会最终定位和查找模板。与之前配置InternalResourceViewResolver类似,它使用了prefix和suffix属性。前缀和后缀将会与逻辑视图名组合使用,进而定位Thymeleaf引擎。它的templateMode属性被设置成了HTML 5,这表明我们预期要解析的模板会渲染成HTML 5输出
到这里我们就基本配置完了 。
接下来我们在WEB-INF/template下建立home.html,头部加入thymeleaf的命令空间
<html xmlns:th="http://www.thymeleaf.org">
建立一个controller,写我们的第一个controller,打开访问localhost:8080/home就会转发到/WEB-INF/template/home.html
@RequestMapping("/home") public String hello(Map<String,Object> map){ User user = new User("1", "fei", 22, "爱好:篮球","admin"); map.put("user",user); List<User> list = new ArrayList<>(); for(int i =0;i<5;i++){ User u = new User(""+(i+2), "fei"+(i+2), 22+(i+2), "爱好:篮球"+(i+2),"user"+i); list.add(u); } map.put("userList",list); return "home"; }
thymeleaf语法
文本显示
${}的使用和jsp的el表达式很类似,我们在后台绑定了一个user对象那么我们可以通过${user.name}获取用户名,相当于user.getName();但是注意这个只能放到th表达式里面
th:text就相当于把里面的渲染主来的值放到aaa的位置上,如果th:text里面的值只有${user.name},并且为null,那么就会显示aaa
<span th:text="'用户名:' +${user.name}">aaa</span> #或者下面的这种方式,|…|中只能包含变量表达式${…},不能包含其他常量、条件表达式等 <span th:text="|用户名:${user.name}|"></span>
运算符
在表达式中可以使用各类算术运算符,例如+, -, *, /, %
<span th:text="'年龄*2='+ ${user.age}*2 "></span>
逻辑运算符
在表达式中可以使用逻辑运算符,但是除了==其他的要使用转义字符
>, <, >=, <= != 对应(gt, lt, ge, le, ne)
<span th:text="(${user.age} eq 22)">aaa</span> //输出true #可以使用二元表达式 <span th:text="(${user.age} ge 23?'超过年纪':'ok')"></span>
条件判断
th:if条件成立才会显示
th:unless条件不成立才会显示
<span th:if="(${user.age} gt 21)">年龄超过21才会显示</span> <a th:href="@{/login}" th:unless=${session.user != null}>Login</a>
Switch
* 代表default,其他都没匹配到会显示带*的
<div th:switch="${user.role}"> <p th:case="'admin'">用户是管理员</p> <p th:case="*">用户是普通人员</p> </div>
循环
第二个参数称作状态变量,属性有
- index:当前迭代对象的index(从0开始计算)
- count: 当前迭代对象的index(从1开始计算)
- size:被迭代对象的大小
- current:当前迭代变量
- even/odd:布尔值,当前循环是否是偶数/奇数(从0开始计算)
- first:布尔值,当前循环是否是第一个
- last:布尔值,当前循环是否是最后一个
<table> <tr> <th>index</th> <th>id</th> <th>name</th> <th>age</th> </tr> <tr th:each="user,iterStat: ${userList}" > <td th:text="${iterStat.index}">1</td> <td th:text="${user.id}">1</td> <td th:text="${user.name}">王五</td> <td th:text="${user.age}">55</td> </tr> </table>
* 号和$符号共用
*{}里面的值就是上层th:object对象里面对应的属性
<div th:object="${user}"> <p>Name: <span th:text="*{name}">wangwu</span>.</p> <p>AGE: <span th:text="*{age}">22</span>.</p> </div>
Utilities
Utilities为了模板更加易用,Thymeleaf还提供了一系列Utility对象(内置于Context中),可以通过#直接访问
- dates : java.util.Date的功能方法类。
- calendars : 类似#dates,面向java.util.Calendar
- numbers : 格式化数字的功能方法类
- strings : 字符串对象的功能类,contains,startWiths,prepending/appending等等。
- objects: 对objects的功能类操作。
- bools: 对布尔值求值的功能方法。
- arrays:对数组的功能类方法。
- lists: 对lists功能类方法
- sets
- maps
表达式基本对象
- #ctx: 上下文对象.
- #vars: context中的变量们.
- #locale: context中的locale.
- #httpServletRequest: (只在web context中) HttpServletRequest对象.
- #httpSession: (只在web context中) HttpSession对象.
将date渲染成后面的格式 ${#dates.format(date, 'dd/MMM/yyyy HH:mm')} 得到当前时间 ${#dates.createNow()} 得到当前时间并显示 <span th:text=" ${#dates.format(new java.util.Date().getTime(), 'yyyy-MM-dd hh:mm:ss')} "></span>
内联
Text inlining
后面[[]]里面的值是从域中获取的text文本,跟使用th:text效果类似
<span th:inline="text">[[${user.name}]]</span>
JavaScript inlining
<script th:inline="javascript"> var name = [[${user.name}]]; </script>
下面这个意思是如果没有跑在服务器,name就会是我们的lisi,如果在服务器上,会取出user.name的值,忽略lisi
var name = /*[[${user.name}]]*/"lisi";
CSS inlining
<style th:inline="css"> .[[${classname}]] { text-align: [[${align}]]; } </style>
none inlining
但是如果我么就要显示[[${user.name}]]不需要他转换呢,就会用到none inlining
<span th:inline="none">[[${user.name}]]</span>
嵌套
在当前home.html路径下有个footer.html,内容如下
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <body> <footer th:fragment="copy"> © 2011 The Good Thymes Virtual Grocery </footer> </body> </html>
在home.html引用这个footer,footer代表html的名称,copy代表fragmen的值
<div th:replace="footer:: copy"></div> <div th:include="footer:: copy"></div>
展现的源码:
<footer> © 2011 The Good Thymes Virtual Grocery </footer> <div> © 2011 The Good Thymes Virtual Grocery </div>
得出结论:
- th:replace会将当前div整个替换成foot的元素
- th:include只是将footer里面的内容拷贝进来
链接
链接一般用th:href="@{地址}",“@{}”表达式,用来计算相对于URL的路径,在html ==<a href="/register"></a>
<a th:href="@{/register}">register</a>
常用标签
springboot简化配置
当然在springboot中,上面的视图解析器等注册都不需要我们做了,因为springboot都默认帮我们做了,(只要我们将Thymeleaf maven依赖添加到项目的pom文件下,就启用了Spring Boot的自动配置。当应用运行时,Spring Boot将会探测到类路径中的Thymeleaf,然后会自动配置视图解析器、模板解析器以及模板引擎)
如果什么都不配置,springboot会默认查找类跟目录下的templates文件夹下的模板,home.html放到src/main/ resources/templates目录下
如果我们要在home的html中引入一些静态资源怎么办呢,这点springboot也帮我们考虑到了
springboot它会将“/**”映射到几个资源路径中
- META-INF/resources/
- resources
- static
- public
也就是说我们在有一个static/css/home.css
那么我们这样引入就可以了。
<link type="text/css" rel="stylesheet" th:href="@{/css/home.css}"></link>
当然,我们还是可以配置前缀后缀,以及是否缓存等,只需要一个简单的配置即可
#配置前缀 #spring.thymeleaf.prefix=classpath:/templates/ #配置后缀 #spring.thymeleaf.suffix=.html #spring.thymeleaf.mode=HTML5 #spring.thymeleaf.encoding=UTF-8 #spring.thymeleaf.content-type=text/html #是否开启缓存 spring.thymeleaf.cache=false
github代码地址