选择视图模板库

在大多数情况下,视图模板库的选择完全取决于个人喜好。Spring 非常灵活,能够支持很多常见的模板方案。除了个别情况,你所选择的模板库本身甚至不知道它在与 Spring 协作。

表2.2列出了 Spring Boot 自动配置功能所支持的模板方案。

Table 1. 表2.2  支持的模板方案
模板 Spring Boot starter依赖

FreeMarker

spring-boot-starter-freemarker

Groovy Templates

spring-boot-starter-groovy-template

JavaServer Pages(JSP)

无(由Tomcat或Jetty提供)

Mustache

spring-boot-starter-mustache

Thymeleaf

spring-boot-starter-thymeleaf

通常来讲,你只需要选择想要的视图模板库,将其作为依赖项添加到构建文件中,就可以在 “/templates” 目录下(在基于 Maven 或 Gradle 构建的项目中,它会在 “src/main/resources” 目录下)编写模板了。Spring Boot 会探测到你所选择的模板库,并自动配置为 Spring MVC 控制器生成视图所需的各种组件。

在 Taco Cloud 应用中,我们已经按照这种方式使用了 Thymeleaf 模板库。在第 1 章中,在初始化项目的时候,我们选择了 Thymeleaf 复选框。这样会自动将 Spring Boot 的 Thymeleaf starter 依赖添加到 pom.xml 文件中。应用启动时,Spring Boot 的自动配置功能会探测到 Thymeleaf 并自动为我们配置 Thymeleaf bean。我们所需要做的就是在 “/templates” 中开始编写模板。

如果你想要使用不同的模板库,只需要在项目初始化的时候选择它,或者编辑已有的项目构建文件,将新选择的模板库添加进来。

例如,假设我们想要使用 Mustache 来替换 Thymeleaf,没有问题!只需要找到 pom.xml 文件,并将

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

替换为

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

当然,还需要确保按照 Mustache 语法来编写模板,而不是再使用 Thymeleaf 标签。Mustache 的特定用法(以及其他备选模板语言)超出了本书的范围,但是我在这里给你一个直观的印象,让你明白大致会是什么样子,如下代码是 Mustache 模板的一个片段,它能够渲染 taco 设计表单中的某个配料组:

<h3>Designate your wrap:</h3>
{{#wrap}}
<div>
  <input name = "ingredients" type = "checkbox" value = "{{id}}" />
  <span>{{name}}</span><br/>
</div>
{{/wrap}}

这是 2.1.3 小节中 Thymeleaf 代码片段的 Mustache 等价实现。{{#wrap}} 代码块(结尾对应使用 {{/wrap}})会遍历请求中 key 为 wrap 的属性并为每个条目渲染嵌入式 HTML。{{id}}{{name}} 标签分别会引用每个条目(应该是一个 Ingredient)的 id 和 name 属性。

你可能已经注意到了,在表 2.2 中,JSP 并不需要在构建文件中添加任何特殊的依赖。这是因为 Servlet 容器本身(默认是 Tomcat)会实现 JSP 规范,因此不需要额外的依赖。

但是,选择使用 JSP,会带来另一个问题。事实上,Java Servlet 容器,包括嵌入式的 Tomcat 和 Jetty 容器,通常会在 “/WEB-INF” 目录下寻找 JSP 文件。如果将应用构建成一个可执行的 JAR 文件,就无法满足这种需求了。因此,只有在将应用构建为 WAR 文件并部署到传统的 Servlet 容器中时,才能选择 JSP 方案。如果想要构建可执行的 JAR 文件,那么必须选择 Thymeleaf、FreeMarker 或表2.2中的其他方案。

缓存模板

默认情况下,模板只有在第一次使用的时候解析一次,解析的结果会被后续的请求所使用。对于生产环境来说,这是一个很棒的特性,它能防止每次请求时多余的模板解析过程,因此有助于提升性能。

但是,在开发期,这个特性就不太友好了。假设我们启动完应用之后访问 taco 的设计页面,然后决定对它做一些修改,刷新 Web 浏览器的时候,依然会看到原来的版本。要想看到变更效果,必须要重新启动应用,这当然是非常不方便的。

幸运的是,有一种方法可以禁用缓存。我们所需要做的就是将相关的缓存属性设置为 false。表2.3列出了每种模板库所对应的缓存属性。

Table 2. 表2.3  启用或禁用模板缓存的属性
模板 启用或禁用缓存的属性

FreeMarker

spring.freemarker.cache

Groovy Templates

spring.groovy.template.cache

Mustache

spring.mustache.cache

Thymeleaf

spring.thymeleaf.cache

默认情况下,这些属性都设置成了 true,以便启用缓存。我们可以将缓存属性设置为 false,从而禁用所选模板引擎的缓存。例如,要禁用 Thymeleaf 缓存,只需要在 application.properties 中添加这行代码:

spring.thymeleaf.cache = false

唯一需要注意的是,在将应用部署到生产环境之前,一定要删除这一行代码(或者将其设置为 true)。对于这一点,有种方法是将该属性设置到 profile 中(我们将会在第 6 章讨论 profile)。

另外一种更简单的方式是使用 Spring Boot 的 DevTools,与第 1 章中的做法一样。DevTools 提供了很多非常有用的开发期特性,其中有一项功能就是禁用所有模板库的缓存,但是在应用部署的时候,DevTools 会将自身禁用掉(从而能够重新启用模板缓存)。

小结

  • Spring 提供了一个强大的 Web 框架,名为 Spring MVC,它能够用来为 Spring 应用开发 Web 前端。

  • Spring MVC 是基于注解的,通过像 @RequestMapping、@GetMapping 和 @PostMapping 这样的注解来启用请求处理方法的声明。

  • 大多数的请求处理方法最终会返回一个视图的逻辑名称,比如 Thymeleaf 模板,请求会转发到这样的视图上(同时会带有任意的模型数据)。

  • Spring MVC 支持校验,这是通过 JavaBean Validation API 和 Validation API 的实现(如 Hibernate Validator)完成的。

  • 我们可以在 WebMvcConfigurer 类中通过 addViewController 方法注册视图控制器,以处理没有模型数据和业务逻辑的 HTTP GET 请求。

  • 除了 Thymeleaf 之外,Spring 支持各种视图方案,包括 FreeMarker、Groovy Templates 和 Mustache。