On this page
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 中默认提供),并附加要求将MyThing
Comments 为@XmlRootElement
:
@XmlRootElement
public class MyThing {
private String name;
// .. getters and setters
}
要使服务器渲染 XML 而不是 JSON,您可能必须发送Accept: text/xml
Headers(或使用浏览器)。
74.3 自定义 Jackson ObjectMapper
Spring MVC(Client 端和服务器端)使用HttpMessageConverters
来协商 HTTP 交换中的内容转换。如果 Jackson 在 Classpath 中,则您已经获得Jackson2ObjectMapperBuilder
提供的默认转换器,该转换器的实例已为您自动配置。
默认情况下创建的ObjectMapper
(对于 Jackson XML 转换器,则为XmlMapper
)实例具有以下自定义属性:
MapperFeature.DEFAULT_VIEW_INCLUSION
已禁用DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
已禁用
Spring Boot 还具有一些功能,可以更轻松地自定义此行为。
您可以使用环境配置ObjectMapper
和XmlMapper
实例。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 编码的文件数据作为@RequestParam
Comments 类型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
添加到您的上下文中:
Bean ID 为“ defaultViewResolver”的
InternalResourceViewResolver
。这是一个可以使用DefaultServlet
渲染的物理资源(例如,如果使用的是静态资源和 JSP 页面)。它在视图名称中应用前缀和后缀,然后在 Servlet 上下文中查找具有该路径的物理资源(默认值均为空,但可通过spring.mvc.view.prefix
和spring.mvc.view.suffix
进行外部配置访问)。通过提供相同类型的 bean 可以覆盖它。ID 为“ beanNameViewResolver”的
BeanNameViewResolver
。这是视图解析器链的有用成员,它将拾取与要解析的View
相同名称的所有 bean。不必重写或替换它。仅当实际上存在“
View
”类型的 bean 时,才添加 ID 为“ viewResolver”的ContentNegotiatingViewResolver
。这是一个“主”解析器,委派给所有其他解析器,并尝试查找与 Client 端发送的“ Accept” HTTPHeaders 匹配的内容。您可能想学习有用的关于 ContentNegotiatingViewResolver 的博客以了解更多信息,并查看源代码以获取详细信息。您可以通过定义一个名为'viewResolver'的 bean 来关闭自动配置的ContentNegotiatingViewResolver
。如果您使用 Thymeleaf,您还将拥有 ID 为“ thymeleafViewResolver”的
ThymeleafViewResolver
。它通过在视图名称前后加上前缀和后缀(分别扩展为spring.thymeleaf.prefix
和spring.thymeleaf.suffix
,分别默认为'classpath:/ templates /'和'.html')来查找资源。可以通过提供相同名称的 bean 来覆盖它。如果您使用 FreeMarker,您还将拥有 ID 为“ freeMarkerViewResolver”的
FreeMarkerViewResolver
。它通过在视图名称前加上前缀和后缀(分别扩展为spring.freemarker.prefix
和spring.freemarker.suffix
,分别为空和'.ftl)来在加载器路径(扩展为spring.freemarker.templateLoaderPath
,默认为'classpath:/ templates /')中查找资源。可以通过提供相同名称的 bean 来覆盖它。如果您使用 Groovy 模板(实际上,如果您的 Classpath 上有 groovy-templates),您还将拥有一个
GroovyMarkupViewResolver
,其 ID 为'groovyMarkupViewResolver'。它通过在视图名称前加上前缀和后缀(分别扩展为spring.groovy.template.prefix
和spring.groovy.template.suffix
,分别默认为'classpath:/ templates /'和'.tpl')来在加载器路径中查找资源。可以通过提供相同名称的 bean 来覆盖它。
检出WebMvcAutoConfiguration,ThymeleafAutoConfiguration,FreeMarkerAutoConfiguration和GroovyTemplateAutoConfiguration
74.9 使用 Thymeleaf 3
默认情况下,spring-boot-starter-thymeleaf
使用 Thymeleaf 2.1. 如果使用的是spring-boot-starter-parent
,则可以通过覆盖thymeleaf.version
和thymeleaf-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 兼容的版本。