Spring MVC
Spring Boot有许多包含Spring MVC的启动器。请注意,一些启动器包含对Spring MVC的依赖,而不是直接包含它。本节回答有关Spring MVC和Spring Boot的常见问题。
编写JSON REST服务
@RestController
只要Jackson2在类路径中,Spring Boot应用程序中的任何Spring 都应默认呈现JSON响应,如以下示例所示:
1 |
|
只要MyThing
可以通过Jackson2序列化(对于普通的POJO或Groovy对象都是如此),则localhost:8080/thing
默认为它提供JSON表示。请注意,在浏览器中,您有时可能会看到XML响应,因为浏览器倾向于发送更喜欢XML的接受标头。
编写XML REST服务
如果jackson-dataformat-xml
在类路径上有Jackson XML扩展(),则可以使用它来呈现XML响应。我们用于JSON的前一个示例可以使用。要使用Jackson XML渲染器,请将以下依赖项添加到项目中:
1 | <dependency> |
如果Jackson的XML扩展不可用,则使用JAXB(默认情况下在JDK中提供),并附加要求MyThing
注释为 @XmlRootElement
,如以下示例所示:
1 |
|
要使服务器呈现XML而不是JSON,您可能必须发送 Accept: text/xml
标头(或使用浏览器)。
自定义Jackson ObjectMapper
Spring MVC(客户端和服务器端)用于HttpMessageConverters
协商HTTP交换中的内容转换。如果Jackson在类路径上,您已经获得了由其提供的默认转换器Jackson2ObjectMapperBuilder
,其实例将自动为您配置。
该ObjectMapper
(或XmlMapper
为JacksonXML转换器)实例(默认创建)具有以下定义的属性:
MapperFeature.DEFAULT_VIEW_INCLUSION
被禁用DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
被禁用SerializationFeature.WRITE_DATES_AS_TIMESTAMPS
被禁用
Spring Boot还具有一些功能,可以更轻松地自定义此行为。
您可以使用环境配置ObjectMapper
和XmlMapper
实例。Jackson提供了一套广泛的简单开/关功能,可用于配置其处理的各个方面。这些功能在六个enum(在Jackson中)中描述,它们映射到环境中的属性:
枚举 | 属性 | 值 |
---|---|---|
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
。需要注意的是,由于使用了松弛绑定,所以indent_output
不必匹配相应枚举常量的情况,即INDENT_OUTPUT
。
此基于环境的配置应用于自动配置的 Jackson2ObjectMapperBuilder
bean,并应用于使用构建器创建的任何映射器,包括自动配置的ObjectMapper
bean。
上下文Jackson2ObjectMapperBuilder
可以由一个或多个Jackson2ObjectMapperBuilderCustomizer
bean 自定义 。可以订购这样的定制器bean(Boot自己的定制器的顺序为0),允许在Boot定制之前和之后应用其他定制。
任何类型的bean都会com.fasterxml.jackson.databind.Module
自动注册自动配置Jackson2ObjectMapperBuilder
,并应用于ObjectMapper
它创建的任何实例。这为您在应用程序中添加新功能时提供了一种提供自定义模块的全局机制。
如果要ObjectMapper
完全替换默认值,请定义@Bean
该类型的一个并将其标记为,@Primary
或者,如果您更喜欢基于构建器的方法,请定义一个Jackson2ObjectMapperBuilder
@Bean
。请注意,在任何一种情况下,这样做都会禁用所有的自动配置ObjectMapper
。
如果提供任何@Beans
类型MappingJackson2HttpMessageConverter
,则它们将替换MVC配置中的默认值。此外,HttpMessageConverters
还提供了类型的便利bean (如果使用默认的MVC配置,则始终可用)。它有一些有用的方法来访问默认和用户增强的消息转换器。
有关详细信息,请参阅“ 第79.4节 ” ,“自定义@ResponseBody渲染 ”部分和 WebMvcAutoConfiguration
源代码。
自定义@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 配置,则可以完全控制并使用getMessageConverters
from 手动完成所有操作 WebMvcConfigurationSupport
。
有关WebMvcAutoConfiguration
更多详细信息,请参阅 源代码。
处理多部分文件上传
Spring Boot包含Servlet 3 javax.servlet.http.Part
API以支持上传文件。默认情况下,Spring Boot配置Spring MVC,每个文件的最大大小为1MB,单个请求中的文件数据最大为10MB。您可以覆盖这些值,中间数据的存储位置(例如,到/tmp
目录),以及使用MultipartProperties
类中公开的属性将数据刷新到磁盘的阈值。例如,如果要指定文件不受限制,请将spring.servlet.multipart.max-file-size
属性设置为-1
。
当您希望在Spring MVC控制器处理程序方法中接收多部分编码文件数据作为@RequestParam
类型的注释参数时,多部分支持很有用MultipartFile
。
有关MultipartAutoConfiguration
详细信息,请参阅 源代码。
建议使用容器的内置支持进行分段上传,而不是引入其他依赖项,例如Apache Commons File Upload。
关闭Spring MVC DispatcherServlet
默认情况下,所有内容都是从应用程序的根目录(/
)提供的。如果您希望映射到其他路径,可以按如下方式配置:
1 | spring.mvc.servlet.path=/acme |
如果你有额外的servlet,你可以声明一个@Bean
类型Servlet
或 ServletRegistrationBean
每个servlet ,Spring Boot会将它们透明地注册到容器中。因为servlet是以这种方式注册的,所以可以将它们映射到DispatcherServlet
不调用它的子上下文。
配置DispatcherServlet
你自己是不寻常的,但如果你真的需要这样做,还必须提供一种 @Bean
类型DispatcherServletPath
来提供自定义的路径DispatcherServlet
。
关闭默认MVC配置
完全控制MVC配置的最简单方法是为您自己 @Configuration
提供@EnableWebMvc
注释。这样做会将所有MVC配置留在您的手中。
自定义ViewResolvers
AViewResolver
是Spring MVC的一个核心组件,将视图名称转换 @Controller
为实际View
实现。请注意,ViewResolvers
主要用于UI应用程序,而不是REST样式的服务(View
不用于呈现 @ResponseBody
)。有许多实现ViewResolver
可供选择,而Spring本身并不反对你应该使用哪些实现。另一方面,Spring Boot会为您安装一个或两个,具体取决于它在类路径和应用程序上下文中找到的内容。它DispatcherServlet
使用它在应用程序上下文中找到的所有解析器,依次尝试每个解析器直到获得结果,因此,如果添加自己的解析器,则必须知道顺序以及添加解析器的位置。
WebMvcAutoConfiguration
在ViewResolvers
您的上下文中添加以下内容:
- 一个
InternalResourceViewResolver
名为’defaultViewResolver’。这个可以通过使用DefaultServlet
(包括静态资源和JSP页面,如果您使用它们)来查找可以呈现的物理资源。它将前缀和后缀应用于视图名称,然后在servlet上下文中查找具有该路径的物理资源(默认值为空,但可通过spring.mvc.view.prefix
和访问外部配置spring.mvc.view.suffix
)。您可以通过提供相同类型的bean来覆盖它。 - 一个
BeanNameViewResolver
名为’beanNameViewResolver’。这是视图解析器链的一个有用成员,并获取与View
正在解析的名称相同的任何bean 。没有必要覆盖或替换它。 - 一个
ContentNegotiatingViewResolver
名为“ViewResolver的”只如果有添加的 实际类型的豆类View
存在。这是一个“主”解析器,委托给所有其他人,并尝试找到客户端发送的“Accept”HTTP标头的匹配项。有一个有用的 博客ContentNegotiatingViewResolver
,您可能想要学习以了解更多信息,您也可以查看源代码以获取详细信息。您可以ContentNegotiatingViewResolver
通过定义名为“viewResolver”的bean 来关闭自动配置 。 - 如果你使用Thymeleaf,你也有一个
ThymeleafViewResolver
名为’thymeleafViewResolver’。它通过使用前缀和后缀包围视图名称来查找资源。前缀是spring.thymeleaf.prefix
,后缀是spring.thymeleaf.suffix
。前缀和后缀的值分别默认为“classpath:/ templates /”和“.html”。您可以ThymeleafViewResolver
通过提供相同名称的bean 来覆盖 。 - 如果您使用FreeMarker,您还有一个
FreeMarkerViewResolver
名为’freeMarkerViewResolver’。它spring.freemarker.templateLoaderPath
通过用前缀和后缀包围视图名称来查找加载器路径中的资源(外部化并具有默认值’classpath:/ templates /‘)。前缀外部spring.freemarker.prefix
化为,后缀外部化为spring.freemarker.suffix
。前缀和后缀的默认值分别为空和“.ftl”。您可以FreeMarkerViewResolver
通过提供相同名称的bean 来覆盖。- 如果您使用Groovy模板(实际上,如果
groovy-templates
在您的类路径中),您还有一个GroovyMarkupViewResolver
名为groovyMarkupViewResolver
。它通过用前缀和后缀(外部化为spring.groovy.template.prefix
和spring.groovy.template.suffix
)包围视图名称来查找加载器路径中的资源。前缀和后缀分别具有“classpath:/ templates /”和“.tpl”的默认值。您可以GroovyMarkupViewResolver
通过提供相同名称的bean 来覆盖。
- 如果您使用Groovy模板(实际上,如果
有关更多详细信息,请参阅以下部分: