# Spring Boot 视图技术


<!--more-->


## 1.支持的视图技术

前端模板引擎技术的出现，使前端开发人员无需关注后端业务的具体实现，只关注自己页面的呈现效果即可，并且解决了前端代码错综复杂的问题、实现了前后端分离开发。Spring Boot框架对很多常用的模板引擎技术（如：FreeMarker、Thymeleaf、Mustache等）提供了整合支持

Spring Boot不太支持常用的JSP模板，并且没有提供对应的整合配置，这是因为使用嵌入式Servlet容器的Spring Boot应用程序对于JSP模板存在一些限制 ：

- Spring Boot默认使用嵌入式Servlet容器以JAR包方式进行项目打包部署，这种JAR包方式不支持JSP模板。

- 如果使用Undertow嵌入式容器部署Spring Boot项目，也不支持JSP模板。

- Spring Boot默认提供了一个处理请求路径“/error”的统一错误处理器，返回具体的异常信息。使用JSP模板时，无法对默认的错误处理器进行覆盖，只能根据Spring Boot要求在指定位置定制错误页面。

## 2.thymeleaf

### 2.1thymeleaf语法

Thymeleaf是一种现代的基于服务器端的Java模板引擎技术，也是一个优秀的面向Java的XML、XHTML、HTML5页面模板，它具有丰富的标签语言、函数和表达式，在使用Spring Boot框架进行页面设计时，一般会选择Thymeleaf模板

`xmlns:th="http://www.thymeleaf.org"`用于引入thymeleaf模板引擎标签

- 常用标签

  ![示意图](https://img.zhaojq.top/20260727091720531.png "示意图")

- 标准表达式

  ![示意图](https://img.zhaojq.top/20260727091720714.png "示意图")

  同时，Thymeleaf为变量所在域提供了一些内置对象，具体如下所示

  ```text
  # ctx：上下文对象
  # vars：上下文变量
  # locale：上下文区域设置
  # request：（仅限Web Context）HttpServletRequest对象
  # response：（仅限Web Context）HttpServletResponse对象
  # session：（仅限Web Context）HttpSession对象
  # servletContext：（仅限Web Context）ServletContext对象
  ```

  例：`The locale country is: <span th:text="${#locale.country}">US</span>`

  上述代码中，使用th:text="${#locale.country}"动态获取当前用户所在国家信息，其中标签内默认内容为US（美国），程序启动后通过浏览器查看当前页面时，Thymeleaf会通过浏览器语言设置来识别当前用户所在国家信息，从而实现动态替换

- 选择变量表达式

  ```html
  <div th:object="${book}">
  	<p>titile: <span th:text="*{title}">标题</span>.</p>
  </div>
  ```

  *{title} 选择变量表达式获取当前指定对象book的title属性值。

- 消息表达式

  消息表达式#{...}主要用于Thymeleaf模板页面国际化内容的动态替换和展示，使用消息表达式#{...}进行国际化设置时，还需要提供一些国际化配置文件。

- 链接表达式

  链接表达式@{...}一般用于页面跳转或者资源的引入，在Web开发中占据着非常重要的地位，并且使用也非常频繁，示例代码如下：

  ```html
  <a th:href="@{http://localhost:8080/order/details(orderId=${o.id})}">view</a>
  <a th:href="@{/order/details(orderId=${o.id})}">view</a>
  ```

- 片段表达式 ~{...}

  片段表达式~{...}用来标记一个片段模板，并根据需要移动或传递给其他模板。其中，最常见的用法是使用th:insert或th:replace属性插入片段，示例代码如下：

  ```html
  <div th:insert="~{thymeleafDemo::title}"></div>
  ```

  上述代码中，使用th:insert属性将title片段模板引用到该标签中。thymeleafDemo为模板名称，Thymeleaf会自动查找“/resources/templates/”目录下的thymeleafDemo模板，title为片段名称

### 2.2基本使用

- 依赖

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

- 配置

  ```properties
  spring.thymeleaf.cache = true ＃启用模板缓存
  spring.thymeleaf.encoding = UTF-8 ＃模板编码
  spring.thymeleaf.mode = HTML5 ＃应用于模板的模板模式
  spring.thymeleaf.prefix = classpath:/templates/ ＃指定模板页面存放路径
  spring.thymeleaf.suffix = .html ＃指定模板页面名称的后缀
  ```

- 静态资源访问

  使用Spring Initializr方式创建的Spring Boot项目，默认生成了一个resources目录，在resources目录中新建public、resources、static三个子目录下，Spring boot默认会挨个从public、resources、static里面查找静态资源

### 2.3数据页面展示

看示例代码		

### 2.4配置国际化页面

- 编写多语言国际化配置文件

  在项目的类路径resources下创建名称为i18n的文件夹，并在该文件夹中根据需要编写对应的多语言国际化文件login.properties、login_zh_CN.properties和login_en_US.properties文件

- 添加配置

  ```properties
  #配置国际化文件基础名
  spring.messages.basename=i18n.login
  ```

- 定制区域信息解析器

  在完成上一步中多语言国际化文件的编写和配置后，就可以正式在前端页面中结合Thymeleaf模板相关属性进行国际化语言设置和展示了，不过这种实现方式默认是使用请求头中的语言信息（浏览器语言信息）自动进行语言切换的，有些项目还会提供手动语言切换的功能，这就需要定制区域解析器了在项目中创建名为`com.example.demospringbootthymeleaf.config`的包，并在该包下创建一个用于定制国际化功能区域信息解析器的自定义配置类`MyLocalResovel`

  ```java
  @Configuration
  public class MyLocaleResovle implements LocaleResolver {
  
      // 自定义 区域解析方式
      @Override
      public Locale resolveLocale(HttpServletRequest httpServletRequest) {
          // 获取页面手动传递的语言参数值l  : zh_CN  en_US  ''
          String l = httpServletRequest.getParameter("l");
          Locale locale = null;
          if (!StringUtils.isEmpty(l)) {
              // 如果参数不为空，就根据参数值进行手动语言切换
              String[] s = l.split("_");
              locale = new Locale(s[0], s[1]);
          } else {
              //Accept-Language: zh-CN ,zh;q=0.9
              String header = httpServletRequest.getHeader("Accept-Language");
              String[] split = header.split(",");
              String[] split1 = split[0].split("-");
              locale = new Locale(split1[0], split1[1]);
          }
  
  
          return locale;
      }
  
      @Override
      public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {
  
      }
  
      // 将自定义的MyLocaleResovle重新注册成一个类型为LocaleResolver的bean组件
      @Bean
      public LocaleResolver localeResolver() {
          return new MyLocaleResovle();
      }
  
  }
  ```

  








