1 视图模板技术
- 我们熟悉的 JSP 其实只是视图模板技术的一种,除了 JSP 外还有很多其他技术也可以帮助我们实现服务器端渲染。日路:Freemarker、Thymeleaf、Velocity等等。其中最优秀的是 Thymeleaf,而 JSP 因为不容易从 jar 包中读取而不被 SpringBoot 所推荐
为什么要使用 Thymeleaf 替代 jsp?
- 前端工程师拿到 jsp 文件后,没法直接在浏览器上查看布局、动态效果等等显示效果。所以基于 jsp 无法和前端工程师进行协同工作。而 Thymeleaf 中所有的动态效果都不影响原本 HTML 标签的显示。当一个前端工程师拿到 Thymeleaf 文件后,可以直接放在浏览器上查看显示效果,也无需启动服务器(如 Tomcat)后才能显示效果,看代码时忽略动态部分即可
2 使用
1、新建工程,导入依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependency>
</dependencies>
2、创建启动类 SpringBootMainType
@SpringBootApplication
public class SpringBootMainType {
public static void main(String[] args) {
SpringApplication.run(SpringBootMainType.class, args);
}
}
3、编写 Handler:TestTemplateHandler
@Controller
public class TestTemplateHandler {
@RequestMapping("/test/thymeleaf")
public String testThymeleaf(){
return "hello";
}
}
4、创建配置文件 application.yml,用于指定上哪找 Thymeleaf 文件,类似视图解析器
spring:
thymeleaf:
prefix: classpath:/templates/
suffix: .html
cache: false
5、创建 Hello.html
注意添加 xmlns:th=“http://www.thymeleaf.org” 名称空间,Thymeleaf 才会生效
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--服务器解析 Thymeleaf 代码时,会读取 th:text 属性的值,用这个值替换原本标签体的值-->
<p th:text="经过服务器处理后可以看到的内容">直接在浏览器上打开时可以看到的内容</p>
</body>
</html>
6、直接双击打开 Hello.html 查看效果:
7、启动 SpringBoot,使用请求访问 Hello.html,查看效果:
3 Thymeleaf 相关语法
使用 Thymeleaf 前要加入名称空间:
<html lang="en" xmlns:th="http://www.thymeleaf.org">
修改标签文本值
<p th:text="新值">原始值</p>
修改指定属性值
<input value="原始值" th:value="新值" />
- 当然这个不仅仅对 value 生效,对其他属性均生效,如 img 标签的 src 属性,可以使用 th:src 重新指定;div 的 style 属性,可以使用 th:style 重新指定
<div style="background-color: yellow" th:style="'background-color: green'"></div>
浏览器打开:
经过服务器访问:
在表达式中访问属性域
<p th:text="${attrNameRequestScope}">访问请求域方式1</p>
<p th:text="${#httpServletRequest.getAttribute('attrNameRequestScope')}">访问请求域方式2</p>
<p th:text="${session.attrNameSessionScope}">访问会话域</p>
<p th:text="${application.attrNameAppScope}">访问应用域</p>
编写 Handler 传递相应的数据
@RequestMapping("/test/thymeleaf")
public String testThymeleaf(ModelMap modelMap, HttpSession session){
// 将测试数据存入请求域
modelMap.addAttribute("attrNameRequestScope", "attrValueRequestScope");
// 将测试数据存入会话域
session.setAttribute("attrNameSessionScope", "attrValueSessionScope");
// 将测试数据存入应用域
servletContext.setAttribute("attrNameAppScope", "attrValueAppScope");
return "hello";
}
浏览器访问如下:
解析 URL 地址
- @{}的作用是把 contextPath 的值赋加到指定的地址前,但 SpringBoot 默认的 contextPath 是空
<p th:text="@{/aaa/bbb/ccc}"></p>
使用场景:超链接的 href 或表单的 action
<a href="../aaa/bbb/ccc.html" th:href="@{/aaa/bbb/ccc.html}"></a>
在服务器访问时,它会自动在 /aaa/bbb/ccc.html 前加上 contextPath,实现动态获取
包含其他模板文件
创建一个模板文件part.html
<div th:fragment="myFirstPart">
<p>will be include content [first]</p>
</div>
<div th:fragment="mySecondPart">
<p>will be include content [Second]</p>
</div>
<div th:fragment="myThirdPart">
<p>will be include content [Third]</p>
</div>
在 hello.html 中有三种方式导入
- include 是包含方式,只会将
<p>will be include content [first]</p>
插入到 div 中 - insert 是插入方式,会将整个 div 插入到原来的 div 中
- replace 是替换方式,将整个 div 与原来的 div 替换
<div th:include="~{include/part::myFirstPart}"></div>
<div th:insert="~{include/part::mySecondPart}"></div>
<div th:replace="~{include/part::myThirdPart}"></div>