只要添加的有Jackson2依赖,Spring Boot应用中的任何@RestController
默认都会渲染为JSON响应,例如:
@RestController
public class MyController {
@RequestMapping("/thing")
public MyThing thing() {
return new MyThing();
}
}
只要MyThing
能够通过Jackson2序列化(比如,一个标准的POJO或Groovy对象),默认localhost:8080/thing将响应一个JSON数据。有时在浏览器中你可能看到XML响应,因为浏览器倾向于发送XML accept headers。
如果classpath下存在Jackson XML扩展(jackson-dataformat-xml
),它会被用来渲染XML响应,示例和JSON的非常相似。想要使用它,只需为你的项目添加以下依赖:
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
你可能还需要添加Woodstox的依赖,它比JDK提供的默认StAX实现快很多,并且支持良好的格式化输出,提高了namespace处理能力:
<dependency>
<groupId>org.codehaus.woodstox</groupId>
<artifactId>woodstox-core-asl</artifactId>
</dependency>
如果Jackson的XML扩展不可用,Spring Boot将使用JAXB(JDK默认提供),不过MyThing
需要注解@XmlRootElement
:
@XmlRootElement
public class MyThing {
private String name;
// .. getters and setters
}
想要服务器渲染XML而不是JSON,你可能需要发送一个Accept: text/xml
头部(或使用浏览器)。
在一个HTTP交互中,Spring MVC(客户端和服务端)使用HttpMessageConverters
协商内容转换。如果classpath下存在Jackson,你就获取到Jackson2ObjectMapperBuilder
提供的默认转换器,这是Spring Boot为你自动配置的实例。
创建的ObjectMapper
(或用于Jackson XML转换的XmlMapper
)实例默认有以下自定义属性:
MapperFeature.DEFAULT_VIEW_INCLUSION
,默认是禁用的DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
,默认是禁用的Spring Boot也有一些用于简化自定义该行为的特性。
你可以使用当前的environment配置ObjectMapper
和XmlMapper
实例。Jackson提供一个扩展套件,可以用来关闭或开启一些特性,你可以用它们配置Jackson以处理不同方面。这些特性在Jackson中是使用6个枚举进行描述的,并被映射到environment的属性上:
Jackson枚举 | Environment属性 |
---|---|
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.serialization-inclusion=always|non_null|non_absent|non_default|non_empty |
例如,设置spring.jackson.serialization.indent_output=true
可以美化打印输出(pretty print)。注意,由于松散绑定的使用,indent_output
不必匹配对应的枚举常量INDENT_OUTPUT
。
基于environment的配置会应用到自动配置的Jackson2ObjectMapperBuilder
bean,然后应用到通过该builder创建的mappers,包括自动配置的ObjectMapper
bean。
ApplicationContext
中的Jackson2ObjectMapperBuilder
可以通过Jackson2ObjectMapperBuilderCustomizer
bean自定义。这些customizer beans可以排序,Spring Boot自己的customizer序号为0,其他自定义可以应用到Spring Boot自定义之前或之后。
所有类型为com.fasterxml.jackson.databind.Module
的beans都会自动注册到自动配置的Jackson2ObjectMapperBuilder
,并应用到它创建的任何ObjectMapper
实例。这提供了一种全局机制,用于在为应用添加新特性时贡献自定义模块。
如果想完全替换默认的ObjectMapper
,你既可以定义该类型的@Bean
并注解@Primary
,也可以定义Jackson2ObjectMapperBuilder
@Bean
,通过builder构建。注意不管哪种方式都会禁用所有的自动配置ObjectMapper
。
如果你提供MappingJackson2HttpMessageConverter
类型的@Bean
,它们将替换MVC配置中的默认值。Spring Boot也提供了一个HttpMessageConverters
类型的便利bean(如果你使用MVC默认配置,那它就总是可用的),它提供了一些有用的方法来获取默认和用户增强的消息转换器(message converters)。具体详情可参考Section 71.4, “Customize the @ResponseBody rendering”及WebMvcAutoConfiguration源码。
Spring使用HttpMessageConverters
渲染@ResponseBody
(或来自@RestController
的响应),你可以通过在Spring Boot上下文中添加该类型的beans来贡献其他的转换器。如果你添加的bean类型默认已经包含了(像用于JSON转换的MappingJackson2HttpMessageConverter
),那它将替换默认的。Spring Boot提供一个方便的HttpMessageConverters
类型的bean,它有一些有用的方法可以访问默认的和用户增强的message转换器(比如你想要手动将它们注入到一个自定义的RestTemplate
时就很有用)。
在通常的MVC用例中,任何你提供的WebMvcConfigurerAdapter
beans通过覆盖configureMessageConverters
方法也能贡献转换器,但不同于通常的MVC,你可以只提供你需要的转换器(因为Spring Boot使用相同的机制来贡献它默认的转换器)。最终,如果你通过提供自己的@EnableWebMvc
注解覆盖Spring Boot默认的MVC配置,那你就可以完全控制,并使用来自WebMvcConfigurationSupport
的getMessageConverters
手动做任何事。
更多详情可参考WebMvcAutoConfiguration源码。
Spring Boot采用Servlet 3 javax.servlet.http.Part
API来支持文件上传。默认情况下,Spring Boot配置Spring MVC在单个请求中只处理每个文件最大1Mb,最多10Mb的文件数据。你可以覆盖那些值,也可以设置临时文件存储的位置(比如,存储到/tmp
文件夹下)及传递数据刷新到磁盘的阀值(通过使用MultipartProperties
类暴露的属性)。如果你需要设置文件不受限制,可以设置spring.http.multipart.max-file-size
属性值为-1
。
当你想要接收multipart编码文件数据作为Spring MVC控制器(controller)处理方法中被@RequestParam
注解的MultipartFile
类型的参数时,multipart支持就非常有用了。
更多详情可参考MultipartAutoConfiguration源码。
Spring Boot想要服务来自应用程序root /
下的所有内容。如果你想将自己的servlet映射到该目录下也是可以的,但当然你可能失去一些Spring Boot MVC特性。为了添加你自己的servlet,并将它映射到root资源,你只需声明一个Servlet
类型的@Bean
,并给它特定的bean名称dispatcherServlet
(如果只想关闭但不替换它,你可以使用该名称创建不同类型的bean)。
完全控制MVC配置的最简单方式是提供你自己的被@EnableWebMvc
注解的@Configuration
,这样所有的MVC配置都逃不出你的掌心。
ViewResolver
是Spring MVC的核心组件,它负责转换@Controller
中的视图名称到实际的View
实现。注意ViewResolvers
主要用在UI应用中,而不是REST风格的服务(View
不是用来渲染@ResponseBody
的)。Spring有很多你可以选择的ViewResolver
实现,并且Spring自己对如何选择相应实现也没发表意见。另一方面,Spring Boot会根据classpath上的依赖和应用上下文为你安装一或两个ViewResolver
实现。DispatcherServlet
使用所有在应用上下文中找到的解析器(resolvers),并依次尝试每一个直到它获取到结果,所以如果你正在添加自己的解析器,那就要小心顺序和你的解析器添加的位置。
WebMvcAutoConfiguration
将会为你的上下文添加以下ViewResolvers
:
defaultViewResolver
的InternalResourceViewResolver
,它会定位可以使用DefaultServlet
渲染的物理资源(比如静态资源和JSP页面)。它在视图名上应用了一个前缀和后缀(默认都为空,但你可以通过spring.view.prefix
和spring.view.suffix
设置),然后查找在servlet上下文中具有该路径的物理资源,可以通过提供相同类型的bean覆盖它。beanNameViewResolver
的BeanNameViewResolver
,它是视图解析器链的一个非常有用的成员,可以在View
解析时收集任何具有相同名称的beans,没必要覆盖或替换它。viewResolver
的ContentNegotiatingViewResolver
,它只会在实际View
类型的beans出现时添加。这是一个'master'解析器,它的职责会代理给其他解析器,它会尝试找到客户端发送的一个匹配'Accept'的HTTP头部。这有一篇关于ContentNegotiatingViewResolver的博客,你也可以也查看下源码。通过定义一个名叫'viewResolver'的bean,你可以关闭自动配置的ContentNegotiatingViewResolver
。thymeleafViewResolver
的ThymeleafViewResolver
,它会通过加前缀和后缀的视图名来查找资源(外部配置为spring.thymeleaf.prefix
和spring.thymeleaf.suffix
,对应的默认为'classpath:/templates/'和'.html')。你可以通过提供相同名称的bean来覆盖它。freeMarkerViewResolver
的FreeMarkerViewResolver
,它会使用加前缀和后缀(外部配置为spring.freemarker.prefix
和spring.freemarker.suffix
,对应的默认值为空和'.ftl')的视图名从加载路径(外部配置为spring.freemarker.templateLoaderPath
,默认为'classpath:/templates/')下查找资源。你可以通过提供相同名称的bean来覆盖它。groovyTemplateViewResolver
的Groovy TemplateViewResolver
,它会使用加前缀和后缀(外部属性为spring.groovy.template.prefix
和spring.groovy.template.suffix
,对应的默认值为'classpath:/templates/'和'.tpl')的视图名从加载路径下查找资源。你可以通过提供相同名称的bean来覆盖它。velocityViewResolver
的VelocityViewResolver
,它会使用加前缀和后缀(外部属性为spring.velocity.prefix
和spring.velocity.suffix
,对应的默认值为空和'.vm')的视图名从加载路径(外部属性为spring.velocity.resourceLoaderPath
,默认为'classpath:/templates/')下查找资源。你可以通过提供相同名称的bean来覆盖它。更多详情可查看源码: WebMvcAutoConfiguration,ThymeleafAutoConfiguration,FreeMarkerAutoConfiguration,GroovyTemplateAutoConfiguration,VelocityAutoConfiguration。
默认情况下,Spring Boot会配置一个VelocityViewResolver
,如果需要的是VelocityLayoutViewResolver
,你可以自己创建一个名为velocityViewResolver
的bean。你也可以将VelocityProperties
实例注入到自定义视图解析器以获取基本的默认设置。
以下示例使用VelocityLayoutViewResolver
替换自动配置的velocity视图解析器,并自定义layoutUrl
及应用所有自动配置的属性:
@Bean(name = "velocityViewResolver")
public VelocityLayoutViewResolver velocityViewResolver(VelocityProperties properties) {
VelocityLayoutViewResolver resolver = new VelocityLayoutViewResolver();
properties.applyToViewResolver(resolver);
resolver.setLayoutUrl("layout/default.vm");
return resolver;
}
默认情况下,spring-boot-starter-thymeleaf
使用的是Thymeleaf 2.1,你可以通过覆盖thymeleaf.version
和thymeleaf-layout-dialect.version
属性使用Thymeleaf 3,例如:
<properties>
<thymeleaf.version>3.0.0.RELEASE</thymeleaf.version>
<thymeleaf-layout-dialect.version>2.0.0</thymeleaf-layout-dialect.version>
</dependency>
为了避免关于HTML 5模板模式过期,将使用HTML模板模式的警告提醒,你需要显式配置spring.thymeleaf.mode
为HTML
,例如:
spring.thymeleaf.mode: HTML
具体操作可查看Thymeleaf 3示例。
如果正在使用其他自动配置的Thymeleaf附加组件(Spring Security,Data Attribute或Java 8 Time),你需要使用兼容Thymeleaf 3.0的版本覆盖它们现在的版本。