79. Spring MVC

Spring Boot 有许多启动器,其中包括 Spring MVC。请注意,一些 Starter 者包括对 Spring MVC 的依赖,而不是直接包含它。本部分回答有关 Spring MVC 和 Spring Boot 的常见问题。

79.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 对象为 true),则默认情况下localhost:8080/thing为其提供 JSON 表示。请注意,在浏览器中,有时可能会看到 XML 响应,因为浏览器倾向于发送更喜欢 XML 的接受 Headers。

79.2 编写 XML REST 服务

如果 Classpath 上具有 Jackson XML extensions(jackson-dataformat-xml),则可以使用它来渲染 XML 响应。我们用于 JSON 的先前示例可以正常工作。要使用 Jackson XML 渲染器,请将以下依赖项添加到您的项目中:

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

如果无法使用 Jackson 的 XML extensions,则使用 JAXB(JDK 中默认提供),另外要求将MyThing标注为@XmlRootElement,如以下示例所示:

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

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

79.3 自定义 Jackson ObjectMapper

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

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

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

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

Enum Property Values
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 bindingindent_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的所有自动配置。

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

有关更多详细信息,请参见“ 第 79.4 节“自定义@ResponseBody 渲染””部分和WebMvcAutoConfiguration源代码。

79.4 自定义@ResponseBody 渲染

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

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

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

79.5 处理分段文件上传

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

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

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

Note

建议使用容器的内置支持进行分段上传,而不要引入其他依赖项,例如 Apache Commons File Upload。

79.6 关闭 Spring MVC DispatcherServlet

默认情况下,所有内容均从应用程序的根目录(/)提供。如果您希望 Map 到其他路径,则可以如下配置:

spring.mvc.servlet.path=/acme

如果您还有其他 servlet,则可以为每个 servlet 声明ServletServletRegistrationBean类型的@Bean,Spring Boot 会将它们透明地注册到容器中。因为 servlet 是通过这种方式注册的,所以可以将它们 Map 到DispatcherServlet的子上下文而无需调用它。

自己配置DispatcherServlet是不寻常的,但如果确实需要配置,则还必须提供DispatcherServletPath类型的@Bean以提供自定义DispatcherServlet的路径。

79.7 关闭默认的 MVC 配置

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

79.8 自定义 ViewResolvers

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

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

有关更多详细信息,请参见以下部分:

上一章 首页 下一章