Spring MVC

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

编写JSON REST服务

@RestController只要Jackson2在类路径中,Spring Boot应用程序中的任何Spring 都应默认呈现JSON响应,如以下示例所示:

1
2
3
4
5
6
7
8
@RestController
public class MyController {

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

只要MyThing可以通过Jackson2序列化(对于普通的POJO或Groovy对象都是如此),则localhost:8080/thing默认为它提供JSON表示。请注意,在浏览器中,您有时可能会看到XML响应,因为浏览器倾向于发送更喜欢XML的接受标头。

编写XML REST服务

如果jackson-dataformat-xml在类路径上有Jackson XML扩展(),则可以使用它来呈现XML响应。我们用于JSON的前一个示例可以使用。要使用Jackson XML渲染器,请将以下依赖项添加到项目中:

1
2
3
4
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>

如果Jackson的XML扩展不可用,则使用JAXB(默认情况下在JDK中提供),并附加要求MyThing注释为 @XmlRootElement,如以下示例所示:

1
2
3
4
5
@XmlRootElement
public class MyThing {
private String name;
// .. getters and setters
}

要使服务器呈现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还具有一些功能,可以更轻松地自定义此行为。

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

枚举 属性
com.fasterxml.jackson.databind.DeserializationFeature spring.jackson.deserialization.<feature_name> truefalse
com.fasterxml.jackson.core.JsonGenerator.Feature spring.jackson.generator.<feature_name> truefalse
com.fasterxml.jackson.databind.MapperFeature spring.jackson.mapper.<feature_name> truefalse
com.fasterxml.jackson.core.JsonParser.Feature spring.jackson.parser.<feature_name> truefalse
com.fasterxml.jackson.databind.SerializationFeature spring.jackson.serialization.<feature_name> truefalse
com.fasterxml.jackson.annotation.JsonInclude.Include spring.jackson.default-property-inclusion alwaysnon_nullnon_absentnon_defaultnon_empty

例如,要启用漂亮打印,请设置spring.jackson.serialization.indent_output=true。需要注意的是,由于使用了松弛绑定,所以indent_output不必匹配相应枚举常量的情况,即INDENT_OUTPUT

此基于环境的配置应用于自动配置的 Jackson2ObjectMapperBuilderbean,并应用于使用构建器创建的任何映射器,包括自动配置的ObjectMapperbean。

上下文Jackson2ObjectMapperBuilder可以由一个或多个Jackson2ObjectMapperBuilderCustomizerbean 自定义 。可以订购这样的定制器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是默认包含的类型(例如MappingJackson2HttpMessageConverterJSON转换),则它将替换默认值。HttpMessageConverters提供了类型的便利bean, 如果您使用默认的MVC配置,它始终可用。它有一些有用的方法来访问默认和用户增强的消息转换器(例如,如果要手动将它们注入自定义,它可能很有用RestTemplate)。

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

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

处理多部分文件上传

Spring Boot包含Servlet 3 javax.servlet.http.PartAPI以支持上传文件。默认情况下,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类型ServletServletRegistrationBean每个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使用它在应用程序上下文中找到的所有解析器,依次尝试每个解析器直到获得结果,因此,如果添加自己的解析器,则必须知道顺序以及添加解析器的位置。

WebMvcAutoConfigurationViewResolvers您的上下文中添加以下内容:

  • 一个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.prefixspring.groovy.template.suffix)包围视图名称来查找加载器路径中的资源。前缀和后缀分别具有“classpath:/ templates /”和“.tpl”的默认值。您可以GroovyMarkupViewResolver通过提供相同名称的bean 来覆盖。

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