首页 > 编程笔记 > Java笔记 阅读:2

thymeleaf是什么,thymeleaf简介(附带实例)

Thymeleaf 是一个现代化的、渲染 XML/XHTML/HTML5 等内容的、服务端的 Java 模板引擎。

类似 JSP、Velocity、FreeMaker 等,Thymeleaf 可以与 Spring MVC 等 Web 框架进行集成,作为 Web 应用的模板引擎。它的主要作用是在静态页面上渲染显示动态数据。

面向于后端开发人员,Thymeleaf 最大的优势就是,它是一个自然语言的模板,语法非常简单,相比其他模板引擎,上手较快,比较适合简单的单体应用。不足之处在于,Thymeleaf 不是高性能的模板引擎,如果我们要开发高并发应用,并且需要实现页面跳转功能,最好使用前后端分离技术。

另外值得一提的是,Thymeleaf 是 SpringBoot 官方推荐使用的视图模板技术,能够与 SpringBoot 完美整合,而且 Thymeleaf 不经过服务器端运算仍然可以直接查看原始值,对于前端工程师而言,同样很友好。

使用 Thymeleaf 渲染的前端页面,示例代码如下:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <p th:text="${username}">Original Value</p>
</body>
</html>
其中,username 是被放在请求域中的数据,通过上述代码的方式,可以将该属性对应的具体值渲染到页面中。

物理视图和逻辑视图

Servlet 中,将请求转发到一个 HTML 页面文件时,使用完整的转发路径,被称为物理视图。

例如,对于该项目的 login_success.html 页面,对应的物理视图为“/pages/user/login_success.html”,项目的目录结构如下图所示:


图 1 项目的目录结构

如果我们把所有的 HTML 页面都放在某个统一的目录下,那么转发地址就会呈现出明显的规律。


综上可知,路径的开头均为“/pages/user/”,路径的结尾均为“.html”。为了方便管理,把完整的路径分为三部分,并进行了统一命名,路径开头的部分称为视图前缀,路径结尾的部分称为视图后缀,路径中间不同的部分称为逻辑视图,如下表所示。也就是说,物理视图=视图前缀+逻辑视图+视图后缀。

表:物理视图的划分
物理视图 视图前缀 逻辑视图 视图后缀
/pages/user/login.html /pages/user/ login .html
/pages/user/login_success.html /pages/user/ login_success .html

Thymeleaf入门案例

下面编写一个 Thymeleaf 的入门案例,来进一步了解。

1) 首先创建 Web 项目,命名为“chapter08_thymeleaf”,并创建 lib 文件夹导入所需 jar 包,创建 views 文件夹添加所需页面,目录结构如下图所示:


图 3 目录结构

2) 配置全局初始化参数,设置视图前缀和视图后缀。

在 web.xml 文件中对参数进行配置,示例代码如下。其中 key 值为 view-prefix,该值是可以自定义的,但对应的 value 值,必须根据实际路径确定。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
         http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--配置全局初始化参数:配置 Thymeleaf 视图的前缀和后缀-->
    <context-param>
        <!--key 值是自定义的-->
        <param-name>view-prefix</param-name>
        <!--Value 值是根据你的项目结构分析出来的-->
        <param-value>/views/</param-value>
    </context-param>
    <context-param>
        <param-name>view-suffix</param-name>
        <param-value>.html</param-value>
    </context-param>
</web-app>
需要注意的是,Thymeleaf 只能渲染视图前缀和视图后缀中间的网页文件。不符合视图前缀和视图后缀的其他路径都无法被渲染。

3) 创建 Servlet 基类,命名为 ViewBaseServlet 示例代码如下:
//省略 import 语句

public class ViewBaseServlet extends HttpServlet {
    //模板引擎
    private TemplateEngine templateEngine;

    @Override
    public void init() throws ServletException {
        // 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(600000L);

        // ⑤设置是否缓存
        templateResolver.setCacheable(true);

        // ⑥设置服务器端编码方式
        templateResolver.setCharacterEncoding("utf-8");

        // 4.创建模板引擎对象
        templateEngine = new TemplateEngine();

        // 5.给模板引擎对象设置模板解析器
        templateEngine.setTemplateResolver(templateResolver);
    }

    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());
    }
}
该类暂时不用手动编写,直接复制过来使用即可,后续使用框架编程后,Servlet类将被完全取代。

上述代码中 processTemplate() 方法的功能,就是对静态页面进行动态数据渲染。包含了三个参数:
原理是先通过模板引擎渲染数据,然后转发到指定页面,由于采用转发方式,所以请求域中的共享数据也是可以传递到客户端的。

4) 编写 index.html 文件创建超链接,单击访问 ThymeleafTestServlet 类,示例代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
    <a href="thymeleafTest">单击访问 ThymeleafTestServlet</a>
</body>
</html>

5) 创建 ThymeleafTestServlet 类,继承 ViewBaseServlet 类,然后调用其 init() 方法进行初始化,调用 processTemplate() 方法实现页面渲染及转发操作。同样使用 @WebServlet 注解将该类注入容器,且映射路径和 index.html 文件中保持一致,为“/thymeleafTest”,示例代码如下:
//省略 import 语句

@WebServlet("/thymeleafTest")
public class ThymeleafTestServlet 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("访问到了 ThymeleafTestServlet");
        String msg="用户名或密码错误";
        //1. 设置共享数据(请求域)
        request.setAttribute("msg",msg);
        //2. 进行转发操作(/views/admin.html)
        this.processTemplate("admin",request,response);
    }
}
在 views 目录下创建 admin.html 文件,引入 Thymeleaf 名称空间,通过 Thymeleaf 的表达式从请求域对象中取值,示例代码如下:
<!DOCTYPE html>
<!--在 html 标签内通过属性方式引入 Thymeleaf 名称空间-->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>admin</title>
</head>
<body>
    <h1>admin 页面</h1>
    <!--通过 Thymeleaf 的表达式从请求域对象中取值-->
    <h2 th:text="${msg}">这是显示后台数据的位置</h2>
</body>
</html>

6) 运行代码,首页的效果如下图所示:


图 4 首页的效果
单击此超链接进行页面渲染,渲染后的页面效果如下图所示:


图 5 渲染后的页面效果

同时,查看控制台输出如下结果,表示成功访问 ThymeleafTestServlet 类,如下图所示:


图 6 查看控制台

相关文章