网络知识 娱乐 SpringBoot2.x 集成 Thymeleaf

SpringBoot2.x 集成 Thymeleaf

本文主要对SpringBoot2.x集成Thymeleaf及其常用语法进行简单总结,其中SpringBoot使用的2.4.5版本。

一、Thymeleaf简介

Thymeleaf是面向Web和独立环境的现代服务器Java模板引擎,能够处理HTML,XML,JavaScript,CSS甚至纯文本。

Thymeleaf旨在提供一个优雅的、高度可维护的创建模板的方式。为了实现这一目标,Thymeleaf建立在自然模板的概念上,将其逻辑注入到模板文件中,不会影响模板设计原型。这改善了设计的沟通,弥合了设计和开发团队之间的差距。

Thymeleaf从设计之初就遵循Web标准——特别是HTML5标准,如果需要,Thymeleaf允许创建完全符合HTML5验证标准的模板。

二、集成Thymeleaf

通过Maven新建一个名为springboot-thymeleaf的项目。

1.引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.8</version>
</dependency>

2.编写配置文件

spring:
  thymeleaf:
    # 在构建URL时附加到视图名称的前缀,默认为classpath:/templates/
    prefix: classpath:/templates/
    # 在构建URL时附加到视图名称的后缀,默认为.html
    suffix: .html
    # 模板模式,默认为HTML
    mode: HTML
    # 模板文件编码,默认为UTF-8
    encoding: UTF-8
    # 是否启用模板缓存,默认为true,表示启用,false不启用
    cache: false
    # 在呈现模板之前是否检查模板存在与否,默认为true
    check-template: true
    # 是否检查模板位置存在与否,默认为true
    check-template-location: true

更多的配置可以查看ThymeleafProperties类:
1

3.准备模板

首先按照配置文件中配置的模板前缀在resources下创建一个templates目录,用于存放模板。然后创建如下名为hello.html的模板:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Hello Thymeleaf</title>
</head>
<body>
    <div>
        <span th:text="${hello}">th:text文本替换会转义html标签,不解析html</span>
    </div>
    <hr/>
    <div>
        <span th:utext="${hello}">th:utext文本替换不会转义html标签,会解析html</span>
    </div>
</body>
</html>

标签中的xmlns:th="http://www.thymeleaf.org声明使用Thymeleaf标签。th:text属性会计算表达式的值将结果设置为标签的标签体。但它会转义HTML标签,HTML标签会直接显示在浏览器上。th:utext属性不会转义HTML标签,HTML标签会被浏览器解析。${hello}是一个变量表达式,它包含一个OGNL(Object-Graph Navigation Language)的表达式,它会从上下文中获取名为hello的变量,然后在模板上进行渲染。

4.Controller层

创建Controller并将模板中要获取的变量设置到Model对象中,如果Controller类上使用的是@Controller注解,则可以返回跟模板名称相同的字符串(不包括前缀和后缀),视图解析器会解析出视图具体地址并生成视图,然后返回给前端控制器进行渲染:

package com.rtxtitanv.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * @author rtxtitanv
 * @version 1.0.0
 * @name com.rtxtitanv.controller.ThymeleafController
 * @description ThymeleafController
 * @date 2021/7/3 19:23
 */
@Controller
public class ThymeleafController {

    @GetMapping("/hello")
    public String hello(Model model) {
        model.addAttribute("hello", "

Hello Thymeleaf

"
); return "hello"; } }

运行项目,浏览器访问http://localhost:8080/hello,发现数据成功渲染到模板:
2
如果Controller类上使用的是@RestController注解,则需要将视图添加到ModelAndView对象中并返回:

package com.rtxtitanv.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author rtxtitanv
 * @version 1.0.0
 * @name com.rtxtitanv.controller.TestController
 * @description TestController
 * @date 2021/7/3 19:43
 */
@RequestMapping("/test")
@RestController
public class TestController {

    @GetMapping("/hello")
    public ModelAndView hello() {
        ModelAndView modelAndView = new ModelAndView("hello");
        modelAndView.addObject("hello", "

hello thymeleaf

"
); return modelAndView; } }

运行项目,浏览器访问http://localhost:8080/test/hello,发现数据成功渲染到模板:
3

三、Thymeleaf常用语法

1.标准表达式

(1)变量表达式

${}表达式实际上是在上下⽂中包含的变量的映射上执行的OGNL(Object-Graph Navigation Language)对象。例如:${session.user.name}

在Spring MVC启用的应用程序中,OGNL将被替换为SpringEL,但其语法与OGNL相似(实际上,在大多数常见情况下完全相同)。

模板variable.html如下:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>变量表达式</title>
</head>
<body>
    <p>变量表达式:${}</p>
    <div>
        <p>id: <span th:text="${user.id}"></span></p>
        <p>username: <span th:text="${user.username}"></span></p>
        <p>password: <span th:text="${user.password}"></span></p>
    </div>
</body>
</html>

User实体类:

package com.rtxtitanv.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author rtxtitanv
 * @version 1.0.0
 * @name com.rtxtitanv.model.User
 * @description User
 * @date 2021/7/3 19:37
 */
@AllArgsConstructor
@NoArgsConstructor
@Data
public class User {
    private Long id;
    private String username;
    private String password;
}

ThymeleafController中新增以下方法:

@GetMapping("/variable")
public String variable(Model model) {
    model.addAttribute("user", new User(1L, "赵云", "qwe123"));
    return "variable";
}

效果:
4
${}表达式中还可以使用基本对象和工具类对象。这些对象都以#开头。基本对象:

  • #ctx:上下文对象。
  • #vars:上下文变量。
  • #locale:上下文区域设置。
  • #request:(仅在Web Contexts中)HttpServletRequest对象。
  • #response:(仅在Web上下⽂中)HttpServletResponse对象。
  • #session:(仅在Web上下⽂中)HttpSession对象。
  • #servletContext:(仅在Web上下⽂中)ServletContext对象。

工具类对象:

  • #execInfo:有关正在处理的模板的信息。
  • #messages:用于在变量表达式中获取外部化消息的方法,与使用#{}语法获取的方式相同。
  • #uris:转义URL/URI部分的方法。
  • #conversions:执行配置的转换服务的方法。
  • #datesjava.util.Date对象的方法。
  • #calendars:类似于#dates,但对应java.util.Calendar对象。
  • #numbers:用于格式化数字对象的方法。
  • #strings:字符串对象的方法。
  • #objects:一般对象的方法。
  • #bools:布尔相关方法。
  • #arrays:Array的方法。
  • #lists:List的方法。
  • #sets:Set的方法。
  • #maps:Map的方法。
  • #aggregates:在数组或集合上创建聚合的方法。
  • #ids:处理可能重复的id属性的方法。

这些对象的详细方法可以查看官方文档:https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#appendix-a-expression-basic-objects。

(2)选择表达式(星号语法)

星号语法*{}计算所选对象而不是整个上下文的表达式。也就是说,只要没有选定的对象(选定对象为th:object属性的表达式结果),$*语法就会完全相同。

模板asterisk.html如下:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>选择表达式(星号语法)</title>
</head>
<body>
    <p>*语法</p>
    <div th:object="${user}">
        <p>id: <span th:text="*{id}"></span></p>
        <p>username: <span th:text="*{username}"></span></p>
        <p>password: <span th:text="*{password}"></span></p>
    </div>
    <p>$语法</p>
    <div>
        <p>id: <span th:text="${user.id}"></span></p>
        <p>username: <span th:text="${user.username}"></span></p>
        <p>password: <span th:text="${user.password}"></span></p>
    </div>
    <p>$和*混合使用</p>
    <div th:object="${user}">
        <p>id: <span th:text="*{id}"></span></p>
        <p>username: <span th:text="${user.username}"></span></p>
        <p>password: <span th:text="*{password}"></span></p>
    </div>
    <p>对象选择到位时所选对象将作为#object表达式变量可⽤于$表达式</p>
    <div th:object="${user}">
        <p>id: <span th:text="${#object.id}"></span></p>
        <p>username: <span th:text="${user.username}"></span></p>
        <p>password: <span th:text="*{password}"></span></p>
    </div>
    <p>没有执⾏对象选择时$和*语法等效</p>
    <div>
        <p>id: <span th:text="*{user.id}"></span></p>
        <p>username: <span th:text="*{user.username}"></span></p>
        <p>password: <span th:text="*{user.password}"></span></p>
    </div>
</body>
</html>

ThymeleafController中新增以下方法:

@GetMapping("/asterisk")
public String star(Model model) {
    model.addAttribute("user", new User(1L, "赵云", "qwe123"));
    return "asterisk";
}

效果:
5

(3)URL表达式

URL表达式的语法为@{}。使用th:href属性可以对链接进行渲染。

模板url.html如下:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>URL表达式</title>
</head>
<body>
    <ol>
        <li><a href="user/one.html" th:href="@{/user/one(id=${user.id})}">设置单个参数</a></li>
        <li><a href="user/list.html" th:href="@{/user/list(username=${user.username},password=${user.password})}">设置多个参数</a></li>
        <li><a href="user/one.html" th:href="@{/user/one/{id}(id=${user.id})}">URL路径中也允许使⽤变量模板(rest风格参数)</a></li>
        <li><a href="user/update.html" th:href="@{${url}(id=${user.id})}">URL基数也可以是计算另⼀个表达式的结果</a></li>
        <li><a href="store/user/update.html" th:href="@{'/store' + ${url}(id=${user.id})}">url基数也可以是计算另⼀个表达式的结果</a></li>
    </ol>
    <hr/>
    
    <form id="login-form" th:action="@{/hello}">
        <button>提交</button>
    </form>
</body>
</html>

注意:

ThymeleafController中新增以下方法:

@GetMapping("/url")
public String url(Model model) {
    model.addAttribute("user", new User(1L, "赵云", "qwe123"));
    model.addAttribute("url", "/user/update");
    return "url";
}

效果:
6
从上到下依次点击5个链接和提交表单的结果:
7

(4)字