编译软件:IntelliJ IDEA 2019.2.4 x64
操作系统:win10 x64 位 家庭版
服务器软件:apache-tomcat-8.5.27
一. 什么是Thymeleaf?
Thymeleaf是一种用于Java web应用程序的服务器端模板引擎,可以将HTML、XML、JavaScript等静态文件与动态数据(如表单数据、数据库中的数据等)结合起来,在服务器端生成动态的Web页面。
简而言之,它的主要作用就是在静态页面上渲染显示动态数据
Thymeleaf的设计目标是使Web开发变得更加自然和可维护。相比于其他模板引擎,Thymeleaf提供了更好的语法支持和功能,例如标记优雅降级、敏捷布局、动态URL、等,因此它被广泛地应用于Spring框架的开发中。
二. MVC
2.1 为什么需要MVC?
- 提高代码的可维护性:MVC模式将应用程序分成三个互不干扰的部分,使代码更加清晰简洁,易于阅读和
- 支持程序的可扩展性和可重用性:MVC模式使得开发人员在修改应用程序时更加轻松自如,只需要修改特定的代码库即可,而不会影响到其他部门的代码。这种思路与基于组件或者服务的方法相似。
- 提升用户体验:MVC模式开发出来的应用程序中,UI
界面(视图)负责直接呈现数据给用户。同时,视图也不包含任何关于业务领域或者实体(模型)的信息。控制器分离了模型和视图,对用户请求进行处理并起到转发作用,使得界面更加优秀、交互式、快速响应让用户体验更好。
2.2 MVC是什么?
MVC,英文全称为Model-View-Controller(模型-视图-控制器),它是一种常用于软件工程中的设计模式
Model模型
: javaBean(User/Book等类)
View视图
: html+服务器的动态数据
什么叫服务器的动态数据?如下图所示
Controller控制器
: 在web阶段可以暂时将Servlet视为控制器
2.3 MVC和三层架构之间的关系及工作流程
MVC的架构关系及相应的工作流程图解如下所示:
工作流程:
当浏览器向服务器发起请求时,请求被Servlet(控制器)所接收,Servlet会根据请求的内容调用Service(业务逻辑层)去处理相应的业务需求,Service会根据业务需要,会调用DAO层去处理数据,DAO层连接数据库获取相应的数据,然后回传数据给Service,Service根据数据处理好业务需求,将结果回传给Servlet,Servlet将结果传给Thymeleaf,让它渲染页面,从而生成的view对象响应给浏览器。
三. Thymeleaf的工作原理
原理:
从上节中的MVC架构工作流程图中可知,当Servlet接收到service(业务层)给的结果的时候,首先是到视图层(Thymeleaf),将动态数据和HTML进行拼接,从而产生一个View对象(视图),将view对象展示在浏览器上(用户看到的就是有动态数据的网页)
四. Thymeleaf的优势
- SpringBoot官方推荐使用的视图模板技术,和SpringBoot完美整合
- 不经过服务器运算仍然可以直接查看原始值,对前端工程师更友好
五. Thymeleaf的准备知识
5.1 物理视图
释义:
在Servlet中,将请求转发到一个HTML页面文件时,使用的完整的转发路径就是物理视图。
如下图所示:
上述图中所有的HTML页面都放在统一的目录(/WEB-INF/pages下),转发地址已经呈现出一种明显的规律。
将上面所有的物理视图抽取出来
/WEB-INF/pages/a.html
/WEB-INF/pages/abc.html
/WEB-INF/pages/admin.html
…
/WEB-INF/pages/index.html
/WEB-INF/pages/root.html
路径的开头都是
:/WEB-INF/pages/
路径的结尾都是
:.html
对此,路径的开头部分我们称之为视图前缀,路径的结尾部分我们称之为视图后缀
5.2 逻辑视图
物理视图:视图前缀+逻辑视图+视图后缀
逻辑视图
:控制页面跳转的位置
例如:物理视图/WEB-INF/pages/a.html ,/WEB-INF/pages/ 是视图前缀,.html是视图后缀,中间的部分a是逻辑视图,即在servlet中页面跳转的代码语句中要写的跳转位置
六. 如何编写第一个Thymeleaf的程序?
程序需求:
在index.html中访问HelloServlet,由HelloServlet传给Thymeleaf,使其将请求域中的数据(这是给服务器的数据)渲染至admin.html,响应给浏览器
步骤:
①导入Thymeleaf的jar包(共8个)
ps:和导入Beanutils的jar包步骤一致,请自行参阅我的这篇博客Servlet 之超详解【2023年最新版】 第九节的内容。
②在web.xml中配置全局初始化参数
<!--thymeleaf的前缀和后缀--> <context-param> <param-name>view-prefix</param-name> <param-value>/pages/</param-value> </context-param> <context-param> <param-name>view-suffix</param-name> <param-value>.html</param-value> </context-param>
③创建Thymeleaf的模板类ViewBaseServlet(直接复制下面的代码,粘贴到自己的项目下ViewBaseServlet中即可),该类是 HttpServlet 的子类,专门处理 Web 应用程序中视图页面的呈现。在后期使用框架时,该类会被取代。
代码演示如下:
import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.WebContext; import org.thymeleaf.templatemode.TemplateMode; import org.thymeleaf.templateresolver.ServletContextTemplateResolver; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class ViewBaseServlet extends HttpServlet { private TemplateEngine templateEngine; @Override public void init() throws ServletException {//对servlet初始化的(对象创建后立刻初始化) // 1.获取ServletContext对象 ServletContext servletContext = this.getServletContext(); // 2.创建Thymeleaf解析器对象 ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(servletContext); // 3.给解析器对象设置参数 // ①HTML是默认模式,明确设置是为了代码更容易理解 templateResolver.setTemplateMode(TemplateMode.HTML); // ②设置前缀 String viewPrefix = servletContext.getInitParameter("view-prefix"); templateResolver.setPrefix(viewPrefix); // ③设置后缀 String viewSuffix = servletContext.getInitParameter("view-suffix"); templateResolver.setSuffix(viewSuffix); // ④设置缓存过期时间(毫秒) templateResolver.setCacheTTLMs(60000L); // ⑤设置是否缓存 templateResolver.setCacheable(true); // ⑥设置服务器端编码方式 templateResolver.setCharacterEncoding("utf-8"); // 4.创建模板引擎对象 templateEngine = new TemplateEngine(); // 5.给模板引擎对象设置模板解析器 templateEngine.setTemplateResolver(templateResolver); } //就是Thymeleaf要进行渲染的方法,后期如果要进行页面的渲染的话,需要调用此方法 protected void processTemplate(String templateName, HttpServletRequest req, HttpServletResponse resp) throws IOException { // 1.设置响应体内容类型和字符集 resp.setContentType("text/html;charset=UTF-8"); // 2.创建WebContext对象 WebContext webContext = new WebContext(req, resp, getServletContext()); // 3.处理模板数据 templateEngine.process(templateName, webContext, resp.getWriter()); } }
注意:ViewBaseServlet类里的
上述红框中的两个名称要和web.xml中全局初始化参数里设置的前缀名和后缀名保持一致,如下图所示
代码演示如下:
④创建HelloServlet(计划用HelloServlet传给thymeleaf去渲染网页,响应给客户端),并在web.xml中设置它的访问路径(/hello)
<!-- 设置访问HelloServlet的路径 /hello --> <servlet> <servlet-name>HelloServlet</servlet-name> <servlet-class>Servlet.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
⑤创建index.html,在其中设置访问HelloServlet的超链接(计划访问后台的HelloServlet)
代码演示如下:
<a href="hello">点击访问HelloServlet</a>
⑥HelloServlet(要通过Thymeleafi进行页面的渲染,需要继承ViewBaseServlet)
代码演示如下:
import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class HelloServlet extends ViewBaseServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("访问到了HelloServlet类中的doGet方法"); //这里假设业务已经处理好了,HelloServlet已经拿到了业务层传过来的结果 System.out.println("HelloServlet已经拿到了业务层的处理结果...."); //给响应(跳转至admin.html,并且msg的数据展示在网页上) String msg="这是给服务器的数据"; //HelloServlet发送给Themeleaf,让它对页面进行渲染 //设置请求域中的共享数据 request.setAttribute("msg",msg); this.processTemplate("admin",request,response);//Themeleaf的原理也是转发 } }
⑦admin.html中需要写thymealf的渲染表达式
代码演示如下:
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>admin页面</h1> <h2 th:text="${msg}">这是服务器传过来的msg</h2> </body> </html>
注意:
要想使用thymealf的渲染表达式,就必须满足下面的两点要求
a.需要在html标签内设置th这个名称空间
示例代码如下:
<html lang="en"xmlns:th="http://www.thymeleaf.org">
b.在一个标签内通过添加属性的方式,让thymeleaf对该标签的标签体内容进行渲染(覆盖)
示例代码如下:
<h2 th:text="${msg}">放服务器传过来的msg数据</h2>
其中 $(msg},是从请求域内获得key值为msg的value值
七.Thymeleaf的基本语法
7.1 th名称空间
Thymeleaf所有的表达式都是通过属性的方式添加,th:表达式内容
添加的位置
:html标签的属性上
xmlns:th="http://www.thymeleaf.org"
7.2 修改标签的文本值(双标签)
语法:
th:text=“新值”
示例代码如下:
<h2 th:text="${msg}">放服务器传过来的msg数据</h2>
从请求域中获取key为msg的value值写入标签体中,原有的标签体内容会被覆盖
7.3 修改标签的属性值(单标签和双标签)
语法:
th:属性名=“新值”
示例代码如下::
<input type="text"value="这是原始值"th:value="${msg}">
7.4 解析URL地址
目的:
拿到urI中的上下文路径
语法:
@{/)
用途:
a.用在base标签上
示例代码如下:
<base href="" th:href="@{/}">
b.作为请求的路径
示例代码如下:
//写法一: <a href="root?id=101&name=jack">Rootservlet01</a> //写法二: <a th:href="@{/root(id=101,name='jack',age=20)}">RootServlet02</a>