Spring MVC
Spring Boot 有许多包括 Spring MVC 的启动器。请注意,某些启动器包含对 Spring MVC 的依赖项,而不是直接包含它。本部分回答有关 Spring MVC 和 Spring Boot 的常见问题。
Write a JSON REST Service
只要类路径上存在 Jackson2,Spring Boot 应用程序中的任何 Spring @RestController
都应默认呈现 JSON 响应,如下例所示:
只要 MyThing
可以由 Jackson2 序列化(对于普通 POJO 或 Groovy 对象为 true),http://localhost:8080/thing
默认提供其 JSON 表示。请注意,在浏览器中,您有时可能会看到 XML 响应,因为浏览器往往会发送首选 XML 的接受标头。
Write an XML REST Service
如果您在类路径上拥有 Jackson XML 扩展(jackson-dataformat-xml
),则可以使用它来呈现 XML 响应。我们用于 JSON 的先前示例将起作用。要使用 Jackson XML 呈现器,请将以下依赖项添加到您的项目:
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
如果没有 Jackson 的 XML 扩展,并且有 JAXB,则可以通过添加对被注释为 @XmlRootElement
的 MyThing
的额外要求,呈现 XML,如下例所示:
您需要确保 JAXB 库是您项目的一部分,例如通过添加:
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
</dependency>
要让服务器呈现 XML 而不是 JSON,您可能需要发送 |
Customize the Jackson ObjectMapper
Spring MVC(客户端和服务器端)使用 HttpMessageConverters
在 HTTP 交换中协商内容转换。如果您在类路径上有 Jackson,那么您已经获得了由 Jackson2ObjectMapperBuilder
提供的默认转换器(实例已为您自动配置)。
ObjectMapper
(或 Jackson XML 转换器的 XmlMapper
)实例(默认创建)具有以下自定义属性:
-
MapperFeature.DEFAULT_VIEW_INCLUSION
is disabled -
DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
is disabled -
SerializationFeature.WRITE_DATES_AS_TIMESTAMPS
is disabled -
SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS
is disabled
Spring Boot 还具有一些功能,可以更轻松地自定义此行为。
您可以使用环境配置 ObjectMapper
和 XmlMapper
实例。Jackson 提供了一套丰富的开关功能,可用于配置其处理的各个方面。这些功能在多个枚举(在 Jackson 中)中进行了描述,该枚举映射到环境中的属性:
Enum | Property | Values |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
configprop:spring.jackson.default-property-inclusion[] |
|
例如,若要启用 pretty print,请设置`spring.jackson.serialization.indent_output=true`。请注意,由于使用了relaxed binding,indent_output`的大小写不必匹配相应枚举常数的大小写,即`INDENT_OUTPUT
。
这种基于环境的配置应用于自动配置的`Jackson2ObjectMapperBuilder`Bean,并应用于使用builder创建的任何映射器,包括自动配置的`ObjectMapper`Bean。
上下文的`Jackson2ObjectMapperBuilder`可以通过一个或多个`Jackson2ObjectMapperBuilderCustomizer`Beans进行定制。此类定制器Beans可以排序(Boot自己的定制器有0的序数),从而允许在Boot定制之前和之后都应用额外的定制。
任何`com.fasterxml.jackson.databind.Module`类型的Bean都会自动注册到自动配置的`Jackson2ObjectMapperBuilder`中,并应用于它创建的任何`ObjectMapper`实例。当您向应用程序中添加新功能时,这种方式提供了一种全局机制,以贡献定制模块。
如果您想完全替换默认的`ObjectMapper`,请为该类型定义一个`@Bean`并将其标记为`@Primary`,或者,如果您更喜欢基于builder的方法,请定义一个`Jackson2ObjectMapperBuilder``@Bean`。请注意,在任何一种情况下,此操作都会禁用`ObjectMapper`的所有自动配置。
如果您提供任何`@Beans`,类型为`MappingJackson2HttpMessageConverter`,它们将替换MVC配置中的默认值。同样地,还提供了一个方便的`HttpMessageConverters`类型Bean(如果您使用默认MVC配置,该类型始终可用)。它有一些有用的方法来访问默认和用户增强消息转换器。
有关更多详情,请参阅"`Customize the @ResponseBody Rendering"部分和{code-spring-boot-autoconfigure-src}/web/servlet/WebMvcAutoConfiguration.java[`WebMvcAutoConfiguration
]源代码。
Customize the @ResponseBody Rendering
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`完全控制并手动执行所有操作。
有关更多详情,请参阅{code-spring-boot-autoconfigure-src}/web/servlet/WebMvcAutoConfiguration.java[WebMvcAutoConfiguration
]源代码。
Handling Multipart File Uploads
Spring Boot包含servlet 5 jakarta.servlet.http.Part`API,以支持文件上传。默认情况下,Spring Boot配置Spring MVC,为每个文件配置最大1MB的大小,在一个请求中的文件数据最大为10MB。您可以覆盖这些值、存储中间数据的位置(例如,到
/tmp`目录)以及使用`MultipartProperties`类中公开的属性将数据刷新到磁盘的阈值。例如,如果您想指定文件不受限制,请将configprop:spring.servlet.multipart.max-file-size[]属性设置为`-1`。
当您想要接收多部分编码文件数据作为Spring MVC控制器处理程序方法中类型为`MultipartFile`的`@RequestParam`-注释的参数时,多部分支持非常有用。
有关更多详情,请参阅{code-spring-boot-autoconfigure-src}/web/servlet/MultipartAutoConfiguration.java[MultipartAutoConfiguration
]源代码。
建议使用容器内置的多部分上传支持,而不是引入一个附加依赖项,如Apache Commons File Upload。 |
Switch Off the Spring MVC DispatcherServlet
默认情况下,所有内容都从您的应用程序根目录提供(/
)。如果您希望映射到不同的路径,则可以按如下方式配置一个:
spring: mvc: servlet: path: "/mypath"
如果您有其他servlet,您可以为每个servlet声明类型为`Servlet`或`ServletRegistrationBean`的`@Bean`,Spring Boot将会将它们透明地注册到容器中。因为servlet就是以这种方式注册的,所以它们可以映射到`DispatcherServlet`的子上下文,而不调用它。
自己配置`DispatcherServlet`是不太常见的,但如果您确实需要这样做,则还必须提供类型为`DispatcherServletPath`的`@Bean`,以提供您的自定义`DispatcherServlet`的路径。
Switch off the Default MVC Configuration
完全控制MVC配置的最简单方法是提供您自己的`@EnableWebMvc`注释的`@Configuration`。这样做会将所有MVC配置都留给您处理。
Customize ViewResolvers
ViewResolver`是Spring MVC的核心组件,它将
@Controller`中的视图名称转换为实际的`View`实现。请注意,ViewResolvers`主要用于UI应用程序,而不是REST风格的服务(`View`不用于呈现
@ResponseBody`)。有多种`ViewResolver`实现可供选择,而且Spring自己不会明确提出意见,建议您使用哪一种。而Spring Boot会根据它在类路径和应用程序上下文中找到的内容,为您安装一个或两个`ViewResolver`。`DispatcherServlet`使用它在应用程序上下文中找到的所有解析器,依次尝试每个解析器,直到获得结果。如果您添加您自己的解析器,您必须注意解析器的顺序和添加的位置。
WebMvcAutoConfiguration
将以下 ViewResolvers
添加到您的上下文中:
-
一个名为 '`defaultViewResolver` 的
InternalResourceViewResolver
。此InternalResourceViewResolver
找到可使用DefaultServlet
渲染的物理资源(包括静态资源和 JSP 页面,如果您使用的话)。它将前缀和后缀应用于视图名称,然后在 servlet 上下文中使用该路径寻找物理资源(默认情况下两者都为空,但可以通过spring.mvc.view.prefix
和spring.mvc.view.suffix
进行外部配置)。您可以通过提供同类型的一个 bean 来覆盖它。 -
一个名为 '`beanNameViewResolver` 的
BeanNameViewResolver
。这是视图解析器链中的一个有用成员,并选取与正在解析的View
同名的任何 bean。没有必要覆盖或替换它。 -
只有当实际上存在类型为
View
的 bean 时,才添加一个名为 '`viewResolver` 的ContentNegotiatingViewResolver
。这是一个复合解析器,委托给所有其他解析器,并尝试查找客户端发送的 '`Accept` HTTP 标头的匹配项。有一个有用的 blog aboutContentNegotiatingViewResolver
可能您愿意研究它来了解更多信息,您还可以查看源代码来获取详细信息。您可以通过定义一个名为 '`viewResolver` 的 bean 来关闭自动配置ContentNegotiatingViewResolver
。 -
如果您使用 Thymeleaf,您还拥有一个名为 '`thymeleafViewResolver` 的
ThymeleafViewResolver
。它通过使用前缀和后缀环绕视图名称来查找资源。前缀是spring.thymeleaf.prefix
,后缀是spring.thymeleaf.suffix
。前缀和后缀的默认值分别为 '`classpath:/templates/` 和 '`.html`。您可以通过提供同名的 bean 来覆盖ThymeleafViewResolver
。 -
如果您使用 FreeMarker,您还拥有一个名为 '`freeMarkerViewResolver` 的
FreeMarkerViewResolver
。它通过使用前缀和后缀环绕视图名称,在加载器路径(已对外化为spring.freemarker.templateLoaderPath
且具有默认值 '`classpath:/templates/)中查找资源。前缀对外化为 `spring.freemarker.prefix
,后缀对外化为spring.freemarker.suffix
。前缀和后缀的默认值分别为空和 '`.ftlh`。您可以通过提供同名的 bean 来覆盖FreeMarkerViewResolver
。 -
如果您使用 Groovy 模板(实际上,如果
groovy-templates
在您的类路径中),您还拥有为名为 '`groovyMarkupViewResolver` 的GroovyMarkupViewResolver
。它通过使用前缀和后缀(对外化为spring.groovy.template.prefix
和spring.groovy.template.suffix
)环绕视图名称,在加载器路径中查找资源。前缀和后缀的默认值分别为 '`classpath:/templates/` 和 '`.tpl`。您可以通过提供同名的 bean 来覆盖GroovyMarkupViewResolver
。 -
如果您使用 Mustache,您还拥有一个名为 '`mustacheViewResolver` 的
MustacheViewResolver
。它通过使用前缀和后缀环绕视图名称来查找资源。前缀是spring.mustache.prefix
,后缀是spring.mustache.suffix
。前缀和后缀的默认值分别为 '`classpath:/templates/` 和 '`.mustache`。您可以通过提供同名的 bean 来覆盖MustacheViewResolver
。
有关更多详细信息,请参阅以下部分:
-
{code-spring-boot-autoconfigure-src}/web/servlet/WebMvcAutoConfiguration.java[
WebMvcAutoConfiguration
] -
{code-spring-boot-autoconfigure-src}/thymeleaf/ThymeleafAutoConfiguration.java[
ThymeleafAutoConfiguration
] -
{code-spring-boot-autoconfigure-src}/freemarker/FreeMarkerAutoConfiguration.java[
FreeMarkerAutoConfiguration
] -
{code-spring-boot-autoconfigure-src}/groovy/template/GroovyTemplateAutoConfiguration.java[
GroovyTemplateAutoConfiguration
]