前言:

本文内容:Thymeleaf模板引擎、Thymeleaf语法、MVC配置原理

推荐免费SpringBoot基础教程视频:【狂神说Java】SpringBoot最新教程通俗易懂_哔哩哔哩_bilibili

Thymeleaf模板引擎

前端交给我们的页面,是html页面。如果是我们以前开发,需要把它们转为jsp页面,jsp好处就是当我们把查询的数据转发到JSP页面,可以用jsp轻松实现数据的显示,及交互等。jsp支持非常强大的功能,包括写Java代码,但是,SpringBoot项目是以jar的方式,不是war;SpringBoot嵌入Tomcat服务器,默认不支持jsp。

那不支持jsp,我们使用纯静态页面的方式,对开发来说比较麻烦,那怎么办呢,SpringBoot推荐你可以使用模板引擎。

那什么是模板引擎,其实jsp就是一个模板引擎,还有之前使用的freemarker,包括SpringBoot给我们推荐的Thymeleaf。

模板引擎的作用就是将获取的数据按照我们所写的表达式进行解析,最后输出到页面。

Thymeleaf

官网:Thymeleaf. (thymeleaf.org)

github:Thymeleaf (github.com)

引入spring-boot-starter-thymeleaf

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

分析源码

1
2
3
4
5
6
7
8
@ConfigurationProperties(prefix = "spring.thymeleaf")
public class ThymeleafProperties {

private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8;
// 模板存放的位置 resources/templates
public static final String DEFAULT_PREFIX = "classpath:/templates/";
// 模板的后缀
public static final String DEFAULT_SUFFIX = ".html";

简单测试

  1. resources/templates下编写test.html

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    </head>
    <body>
    <h1>模板测试</h1>
    </body>
    </html>
  2. HelloController里编写代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    package com.jokerdig.controller;

    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;

    /**
    * @author Joker大雄
    * @data 2022/7/15 - 10:39
    **/
    @Controller
    public class HelloController {

    @RequestMapping("/test")
    public String test(){
    return "test";
    }
    }
  3. 运行测试

    http://localhost:8080/test

    1
    模板测试
  4. 小结

    使用thymeleaf只需要为项目导入对应的依赖,将html页面文件放在template文件夹下即可。

Thymeleaf语法

使用前需要在对应的html中引入约束

1
<html lang="en" xmlns:th="http://www.thymeleaf.org">

标准表达式语法

Thymeleaf 模板引擎支持多种表达式:

  • 变量表达式:${…}
  • 选择变量表达式:*{…}
  • 链接表达式:@{…}
  • 国际化表达式:#{…}
  • 片段引用表达式:~{…}

文字和操作

有很多类型的文字和操作可用,它们分别如下:

  • 文字
    • 文本文字,例如:'one text', 'Another one!',
    • 数字文字,例如:0,10, 314, 31.01, 112.83,
    • 布尔文字,例如:true,false
    • Null文字,例如:Null
    • 文字标记,例如:one, sometext, main,
  • 文本操作:
    • 字符串连接:+
    • 文字替换:|The name is ${name}|
  • 算术运算:
    • 二进制操作:+, -, *, /, %
    • 减号(一元运算符):-
  • 布尔运算:
    • 二进制运算符,and,or
    • 布尔否定(一元运算符):!,not
  • 比较和相等:
    • 比较运算符:>,<,>=,<=(gt,lt,ge,le)
    • 相等运算符:==, != (eq, ne)
  • 条件操作符:
    • If-then:(if) ? (then)
    • If-then-else:(if) ? (then) : (else)
    • Default: (value) ?: (defaultvalue)

th 属性

Thymeleaf 还提供了大量的 th 属性,这些属性可以直接在 HTML 标签中使用,其中常用 th 属性及其示例如下表。

属性 描述
th:id 替换 HTML 的 id 属性
th:text 文本替换,转义特殊字符
th:utext 文本替换,不转义特殊字符
th:object 在父标签选择对象,子标签使用 *{…} 选择表达式选取值。 没有选择对象,那子标签使用选择表达式和 ${…} 变量表达式是一样的效果。 同时即使选择了对象,子标签仍然可以使用变量表达式。
th:value 替换 value 属性
th:with 局部变量赋值运算
th:style 设置样式
th:onclick 点击事件
th:each 遍历,支持 Iterable、Map、数组等。
th:if 根据条件判断是否需要展示此标签
th:unless 和 th:if 判断相反,满足条件时不显示
th:switch 与 Java 的 switch case语句类似 通常与 th:case 配合使用,根据不同的条件展示不同的内容
th:fragment 模板布局,类似 JSP 的 tag,用来定义一段被引用或包含的模板片段
th:insert 布局标签; 将使用 th:fragment 属性指定的模板片段(包含标签)插入到当前标签中。
th:replace 布局标签; 使用 th:fragment 属性指定的模板片段(包含标签)替换当前整个标签。
th:selected select 选择框选中
th:src 替换 HTML 中的 src 属性
th:inline 内联属性; 该属性有 text、none、javascript 三种取值, 在 <script>标签中使用时,js 代码中可以获取到后台传递页面的对象。
th:action 替换表单提交地址

简单测试

  1. 编写HelloController为页面传值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    package com.jokerdig.controller;

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

    import java.util.Arrays;

    /**
    * @author Joker大雄
    * @data 2022/7/15 - 10:39
    **/
    @Controller
    public class HelloController {

    @RequestMapping("/test")
    public String test(Model model){
    model.addAttribute("msg","<h1>Hello SpringBoot</h1>");
    // 集合
    model.addAttribute("users", Arrays.asList("Jokerdig","JokerDaxiong"));
    return "test";
    }
    }
  2. 编写test.html

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    </head>
    <body>
    <!--未转义-->
    <div th:text="${msg}"></div>
    <!--被转义-->
    <div th:utext="${msg}"></div>
    <!--遍历集合th:each-->
    <div th:each="user:${users}" th:text="${user}"></div>
    <!--写法2-->
    <!--<div th:each="user:${users}">[[${user}]]</div>-->
    </body>
    </html>
  3. 运行测试

    1
    2
    3
    <h1>Hello SpringBoot</h1>

    Hello SpringBoot

MVC配置原理

我们还需要知道SpringBoot对SpringMVC还做了哪些配置,包括如何扩展,如何定制等。

官方文档

文档翻译

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Spring MVC Auto-configuration
// Spring Boot为Spring MVC提供了自动配置,它可以很好地与大多数应用程序一起工作。
Spring Boot provides auto-configuration for Spring MVC that works well with most applications.
// 自动配置在Spring默认设置的基础上添加了以下功能:
The auto-configuration adds the following features on top of Spring’s defaults:
// 包含视图解析器
Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.
// 支持静态资源文件夹的路径,以及webjars
Support for serving static resources, including support for WebJars
// 自动注册了Converter:
// 转换器,这就是我们网页提交数据到后台自动封装成为对象的东西,比如把"1"字符串自动转换为int类型
// Formatter:【格式化器,比如页面给我们了一个2022-7-16,它会给我们自动格式化为Date对象】
Automatic registration of Converter, GenericConverter, and Formatter beans.
// HttpMessageConverters
// SpringMVC用来转换Http请求和响应的的,比如我们要把一个User对象转换为JSON字符串,可以去看官网文档解释;
Support for HttpMessageConverters (covered later in this document).
// 定义错误代码生成规则的
Automatic registration of MessageCodesResolver (covered later in this document).
// 首页定制
Static index.html support.
// 图标定制
Custom Favicon support (covered later in this document).
// 初始化数据绑定器:帮我们把请求数据绑定到JavaBean中!
Automatic use of a ConfigurableWebBindingInitializer bean (covered later in this document).

/*
如果您希望保留Spring Boot MVC功能,并且希望添加其他MVC配置(拦截器、格式化程序、视图控制器和其他功能),则可以添加自己
的@configuration类,类型为webmvcconfiguer,但不添加@EnableWebMvc。如果希望提供
RequestMappingHandlerMapping、RequestMappingHandlerAdapter或ExceptionHandlerExceptionResolver的自定义
实例,则可以声明WebMVCregistrationAdapter实例来提供此类组件。
*/
If you want to keep Spring Boot MVC features and you want to add additional MVC configuration
(interceptors, formatters, view controllers, and other features), you can add your own
@Configuration class of type WebMvcConfigurer but without @EnableWebMvc. If you wish to provide
custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter, or
ExceptionHandlerExceptionResolver, you can declare a WebMvcRegistrationsAdapter instance to provide such components.

// 如果您想完全控制Spring MVC,可以添加自己的@Configuration,并用@EnableWebMvc进行注释。
If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc.

自定义视图解析器

新建com.jokerdig.config包,并创建MyMVCConfig.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.jokerdig.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.Locale;

/**
* @author Joker大雄
* @data 2022/7/16 - 13:03
**/
// 扩展SpringMVC
// 如果想要自定义一些功能,只要写好组件,然后将它交给SpringBoot,它就帮我们自动装配
@Configuration
public class MyMVCConfig implements WebMvcConfigurer {
// ViewResolver 实现了视图解析器接口的类,就可以看作视图解析器

// 装配到SpringBoot
@Bean
public ViewResolver myViewResolver(){
return new MyViewResolver();
}


// 自定义一个视图解析器MyViewResolver
public static class MyViewResolver implements ViewResolver{
@Override
public View resolveViewName(String viewName, Locale locale) throws Exception {
return null;
}
}
}

通过Debug打断点测试,发现我们定义的视图解析器也被加载了。

image-20220716132241969