开发工具选用IDEA,尽量选择高版本的Thymeleaf避免版本不兼容问题,使用它可以完全替代JSP。
准备
- 1、pom文件
除了普通的SpringBoot项目,版本选择1.5.10,除了引入Web模块的场景启动器,数据库模块等等之外,还需要thymeleaf的场景启动器,为了兼容性,还需要指定thymeleaf较高的版本 ,pom文件主要的依赖如下(包含但不仅限于,看需求):
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
<relativePath/>
</parent>
<!-- 布局功能的支持程序thymeleaf3主程序 layout2以上版本 -->
<!-- thymeleaf2 SpringBoot的版本是1.5.10 在这里指定较高版本的thymeleaf 3.0.0-->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<thymeleaf.version>3.0.0.RELEASE</thymeleaf.version>
<thymeleaf-layout-dialect.version>2.0.0</thymeleaf-layout-dialect.version>
</properties>
<!--下面这些依赖看需要选择,主要的是这些-->
<dependencies>
<!--模板引擎-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--web模块是一定要的-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
- 2、application.properties文件指定视图解析器
当一个请求被SpringMVC的Controller解析了之后,就会根据这样的视图解析器去找寻对应的html文件,比如,controller返回的字符串结果是“hello”,解析之后的响应的html文件会是/templates/hello.html,这是SpringMVC最简单的使用。
#thymeleaf start
#视图解析器的前缀放在这个文件夹
spring.thymeleaf.prefix=classpath:/templates/
#后缀
spring.thymeleaf.suffix=.html
#模式
spring.thymeleaf.mode=LEGACYHTML5
spring.thymeleaf.servlet.content-type=text/html
#编码格式
spring.thymeleaf.encoding=utf-8
#不用缓存
spring.thymeleaf.cache=false
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
#thymeleaf end
- 3、附上项目结构
使用
1、所有html页面添加头
<html xmlns:th="http://www.thymeleaf.org">
2、引入CSS和JS文件
对比上面给出的目录结构图,不难发现thyleleaf引入资源文件是直接写static目录下的绝对路径即可,语法如下:
<link href="/layui/css/layui.css" th:href="@{/layui/css/layui.css}" rel="stylesheet">
<script src="/js/jquery-1.9.1.min.js" th:src="@{/js/jquery-1.9.1.min.js}"></script>
3、传值给html页面动态显示
在Controller里面使用Model:
@Controller
public class TestController {
/**
* 测试视图解析器
*/
@RequestMapping("/hello")
public String hello(Model model) {
String name = "xiaosha";
model.addAttribute("name", name);
return "hello";
}
}
hello.html页面:
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>hello</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<p th:text="'Hello, ' + ${name} + '!'">3333</p>
</body>
</html>
测试结果:
传递对象
最常用的就是传值到表单,做数据回显,后端Controller在Model存储了一个对象:
@RequestMapping("/getQuestion")
public String getQuestionToForm(Model model) {
Question question = new Question();
question = questionService.getQuestionByWord(word);
model.addAttribute("que",question);
return "questionlist";
}
前端页面这样写:使用${que.word}取出值来
<input type="text" id="word" name="word" th:value="${que!=null}?${que.word}">
<input type="text" id="answer" name="answer" th:value="${que!=null}?${que.answer}">
使用thymeleaf将后端的值在html页面上显示就是这么方便, 不管是字符串、数组、对象、集合大致都差不多,可以直接在页面上进行数据校验,逻辑判断等等。快速入门请参照官方文档: Tutorial: Using Thymeleaf
在JS里面怎么拿取值呢?也是超级简单!
var levle = [[${level}]]; //thymeleaf在Js里面获取SpringMVCModel里面写的值
@RequestMapping(value="/socketQuestion")
public String socketQuestion( Model model,@RequestParam String level){
model.addAttribute("level",level);
return "questionsocket";
}
通常情况下前端想要获取后端的数据是通过Ajax发送异步请求去获取,然后写JS代码去处理这些数据,最后拼接字符串形成html标签,最后被浏览器解析,实现无刷新而更改页面数据。使用了Thymeleaf之后,在JS里面通过[[${ }]]获取值也很方便。
抽取公共元素
在一个网站中,经常是这样的情况,头部、底部、菜单栏等是每个页面都有的,并且功能大致都一样,所以thymeleaf提供了将这些一样的标签页面元素抽取到一个html文件中,当其它html页面有相同的部分需要用到时,直接使用一对标签引入即可。
大致实现步骤,使用一对nav标签,使用 th:fragment=" xxx" 对一部分代码块命名,抽取到一个html页面。
<!--顶栏-->
<nav th:fragment="topbar">
<div class="top">
<div align="right">
<button type="button" class="btn-sign" style="vertical-align:middle"><span>免费注册</span></button>
<button type="button" class="btn-log" style="vertical-align:middle"><span>马上登录</span></button>
</div>
</div>
</nav>
<!--底部信息展示栏-->
<nav th:fragment="bottombar">
<div class="foot" style="background-color:#323232 ;margin-top: 20px;">
<br><br>
<p style="color: #C7C7C7" align="center"><span style="color: #556666;">destiny@XuRuiBiao.com</span> xiaosha</p><br>
<p style="color:#556666" align="center" ;>XXXX公司注册</p><br>
<p style="color:#C7C7C7;" align="center">客服电话:+86-xxxxxxx</p><br>
</div>
</nav>
在其他任何需要这部分页面的地方直接引入即可:
<!--引入公共顶栏-->
<div th:replace="common::topbar"></div>
...
<!--引入公共底部栏-->
<div th:replace="common::bottombar"></div>
附:常用的语法语句
1、获取请求域、Session域里面的数据:
- ${param.x} 返回名为x 的 request参数。(可能有多个值)
- ${session.x} 返回名为x的Session参数。
- ${application.x} 返回名为 servlet context 的参数。
2、日期的输出
<span th:text="${#calendars.format(today,'dd MMMM yyyy')}">13 May 2011</span>
3、循环
<tr th:each="prod : ${prods}">
<td th:text="${prod.name}">Onions</td>
<td th:text="${prod.price}">2.41</td>
<td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
</tr>
4、条件判断
if 和 unless
<a href="comments.html" th:href="@{/comments(prodId=${prod.id})}" th:unless="${#lists.isEmpty(prod.comments)}">view</a>
<a href="comments.html" th:href="@{/product/comments(prodId=${prod.id})}" th:if="${not #lists.isEmpty(prod.comments)}">view</a>
switch
<div th:switch="${user.role}">
<p th:case="'admin'">User is an administrator</p>
<p th:case="#{roles.manager}">User is a manager</p>
<p th:case="*">User is some other thing</p>
</div>