74. Spring MVC

74.1 编写 JSON REST 服务

默认情况下,只要 Jackson2 在 Classpath 上,Spring Boot 应用程序中的任何 Spring @RestController都应渲染 JSON 响应。例如:

@RestController
public class MyController {

    @RequestMapping("/thing")
    public MyThing thing() {
            return new MyThing();
    }

}

只要 Jackson_2 可以序列化MyThing(例如普通的 POJO 或 Groovy 对象),则localhost:8080/thing将默认为其提供 JSON 表示形式。有时在浏览器中您可能会看到 XML 响应,因为浏览器倾向于发送更喜欢 XML 的接受 Headers。

74.2 编写 XML REST 服务

如果您在 Classpath 上具有 Jackson XMLextensions(jackson-dataformat-xml),它将用于渲染 XML 响应,并且可以使用与 JSON 相同的示例。要使用它,请将以下依赖项添加到您的项目中:

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
</dependency>

您可能还想添加对 Woodstox 的依赖。它比 JDK 提供的默认 StAX 实现要快,并且还增加了漂亮的打印支持和改进的名称空间处理:

<dependency>
    <groupId>org.codehaus.woodstox</groupId>
    <artifactId>woodstox-core-asl</artifactId>
</dependency>

如果无法使用 Jackson 的 XMLextensions,则将使用 JAXB(JDK 中默认提供),并附加要求将MyThingComments 为@XmlRootElement

@XmlRootElement
public class MyThing {
    private String name;
    // .. getters and setters
}

要使服务器渲染 XML 而不是 JSON,您可能必须发送Accept: text/xmlHeaders(或使用浏览器)。

74.3 自定义 Jackson ObjectMapper

Spring MVC(Client 端和服务器端)使用HttpMessageConverters来协商 HTTP 交换中的内容转换。如果 Jackson 在 Classpath 中,则您已经获得Jackson2ObjectMapperBuilder提供的默认转换器,该转换器的实例已为您自动配置。

默认情况下创建的ObjectMapper(对于 Jackson XML 转换器,则为XmlMapper)实例具有以下自定义属性:

Spring Boot 还具有一些功能,可以更轻松地自定义此行为。

您可以使用环境配置ObjectMapperXmlMapper实例。Jackson 提供了一套广泛的简单的开/关功能,可用于配置其处理的各个方面。在 Jackson 的六个枚举中描述了这些功能,这些枚举 Map 到环境中的属性:

Jackson enum Environment property
com.fasterxml.jackson.databind.DeserializationFeature spring.jackson.deserialization.<feature_name>=true|false
com.fasterxml.jackson.core.JsonGenerator.Feature spring.jackson.generator.<feature_name>=true|false
com.fasterxml.jackson.databind.MapperFeature spring.jackson.mapper.<feature_name>=true|false
com.fasterxml.jackson.core.JsonParser.Feature spring.jackson.parser.<feature_name>=true|false
com.fasterxml.jackson.databind.SerializationFeature spring.jackson.serialization.<feature_name>=true|false
com.fasterxml.jackson.annotation.JsonInclude.Include spring.jackson.default-property-inclusion=always|non_null|non_absent|non_default|non_empty

例如,要启用漂亮打印,请设置spring.jackson.serialization.indent_output=true。请注意,由于使用了relaxed binding,因此indent_output的情况不必与相应的枚举常量INDENT_OUTPUT的情况相匹配。

这种基于环境的配置将应用于自动配置的Jackson2ObjectMapperBuilder bean,并将应用于使用该构建器创建的任何 Map 器,包括自动配置的ObjectMapper bean。

上下文的Jackson2ObjectMapperBuilder可以由一个或多个Jackson2ObjectMapperBuilderCustomizer bean 进行自定义。可以对此类定制器 bean 进行排序,并且 Boot 自己的定制器的 Sequences 为 0,从而允许在 Boot 定制之前和之后应用其他定制。

任何类型为com.fasterxml.jackson.databind.Module的 bean 都将自动注册到自动配置的Jackson2ObjectMapperBuilder中,并应用于它创建的任何ObjectMapper实例。当您向应用程序中添加新功能时,这提供了一种用于贡献自定义模块的全局机制。

如果要完全替换默认的ObjectMapper,请定义该类型的@Bean并将其标记为@Primary,或者,如果您更喜欢基于构建器的方法,请定义Jackson2ObjectMapperBuilder @Bean。请注意,无论哪种情况,这都将禁用ObjectMapper的所有自动配置。

如果您提供任何类型@Beans@Beans,则它们将替换 MVC 配置中的默认值。另外,还提供了HttpMessageConverters类型的便捷 bean(如果使用默认的 MVC 配置,则始终可用),该便捷 bean 具有一些有用的方法来访问默认的和用户增强的消息转换器。

另请参阅* 第 74.4 节“自定义@ResponseBody 渲染” *部分和WebMvcAutoConfiguration源代码以获取更多详细信息。

74.4 自定义@ResponseBody 渲染

Spring 使用HttpMessageConverters渲染@ResponseBody(或@RestController的响应)。您可以通过在 Spring Boot 上下文中简单地添加该类型的 bean 来贡献额外的转换器。如果您添加的 bean 的类型无论如何都是默认包含的(例如MappingJackson2HttpMessageConverter表示 JSON 转换),它将替换默认值。提供了HttpMessageConverters类型的便捷 bean(如果使用默认的 MVC 配置,则始终可用),该便捷 bean 具有一些有用的方法来访问默认和用户增强的消息转换器(例如,如果您想将其手动注入到自定义RestTemplate中,则很有用.)。

与普通 MVC 用法一样,您提供的任何WebMvcConfigurerAdapter bean 也可以通过重写configureMessageConverters方法来贡献转换器,但是与普通 MVC 不同,您只能提供所需的其他转换器(因为 Spring Boot 使用相同的机制来贡献其默认值)。 。最后,如果您通过提供自己的@EnableWebMvc配置选择退出 Spring Boot 默认 MVC 配置,则可以完全控制并使用WebMvcConfigurationSupport中的getMessageConverters手动进行所有操作。

有关更多详细信息,请参见WebMvcAutoConfiguration源代码。

74.5 处理分段文件上传

Spring Boot 包含 Servlet 3 javax.servlet.http.Part API 以支持上传文件。默认情况下,Spring Boot 用单个请求将 Spring MVC 配置为每个文件最大文件 1MB,最大文件数据 10MB。您可以覆盖这些值,以及使用MultipartProperties类中公开的属性来存储中间数据的位置(例如,存储到/tmp目录)以及将数据刷新到磁盘的阈值。例如,如果要指定文件不受限制,请将spring.http.multipart.max-file-size属性设置为-1

当您想在 Spring MVC 控制器处理程序方法中接收 Multipart 编码的文件数据作为@RequestParamComments 类型MultipartFile的参数时,Multipart 支持会很有帮助。

有关更多详细信息,请参见MultipartAutoConfiguration源。

74.6 关闭 Spring MVC DispatcherServlet

Spring Boot 希望从应用程序/的根目录开始提供所有内容。如果您希望将自己的 servletMap 到该 URL,则可以执行此操作,但是当然您可能会失去其他一些 Boot MVC 功能。要添加您自己的 servlet 并将其 Map 到根资源,只需声明一个类型为Servlet@Bean并为其指定特殊的 Bean 名称dispatcherServlet(如果要关闭它,也可以创建一个具有该名称的其他类型的 Bean,而不必关闭它代替它)。

74.7 关闭默认的 MVC 配置

完全控制 MVC 配置的最简单方法是为自己的@Configuration提供@EnableWebMvc注解。这将使您所有的 MVC 配置都掌握在手中。

74.8 自定义 ViewResolvers

ViewResolver是 Spring MVC 的核心组件,将@Controller中的视图名称转换为实际的View实现。请注意,ViewResolvers主要用于 UI 应用程序,而不是 REST 风格的服务(View不用于渲染@ResponseBody)。 ViewResolver的实现有很多可供选择,而 Spring 本身并未就应该使用哪个实现提出意见。另一方面,Spring Boot 根据在 Classpath 和应用程序上下文中找到的内容为您安装一两个。 DispatcherServlet使用它在应用程序上下文中找到的所有解析器,依次尝试每个解析器直到获得结果,因此,如果要添加自己的解析器,则必须知道 Sequences 以及解析器的添加位置。

WebMvcAutoConfiguration将以下ViewResolvers添加到您的上下文中:

检出WebMvcAutoConfigurationThymeleafAutoConfigurationFreeMarkerAutoConfigurationGroovyTemplateAutoConfiguration

74.9 使用 Thymeleaf 3

默认情况下,spring-boot-starter-thymeleaf使用 Thymeleaf 2.1. 如果使用的是spring-boot-starter-parent,则可以通过覆盖thymeleaf.versionthymeleaf-layout-dialect.version属性来使用 Thymeleaf 3,例如:

<properties>
    <thymeleaf.version>3.0.2.RELEASE</thymeleaf.version>
    <thymeleaf-layout-dialect.version>2.1.1</thymeleaf-layout-dialect.version>
</properties>

Note

如果您要自己 Management 依赖关系,请查看spring-boot-dependencies以获得与这两个版本相关的工件列表。

为避免有关不赞成使用 HTML 5 模板模式而改用 HTML 模板模式的警告消息,您可能还希望将spring.thymeleaf.mode显式配置为HTML,例如:

spring.thymeleaf.mode: HTML

请参阅Thymeleaf 3samples以查看此操作。

如果您正在使用其他任何自动配置的 Thymeleaf Extras(Spring Security,Data Attribute 或 Java 8 Time),则还应将其每个版本覆盖为与 Thymeleaf 3.0 兼容的版本。

上一章 首页 下一章