对于最新的稳定版本,请使用 Spring Boot 3.5.5! |
弹簧 MVC
Spring Boot 有许多Starters,其中包括 Spring MVC。 请注意,一些Starters包含对 Spring MVC 的依赖,而不是直接包含它。 本节回答有关 Spring MVC 和 Spring Boot 的常见问题。
编写 JSON REST 服务
任何弹簧@RestController
在 Spring Boot 应用程序中,只要 Jackson2 在类路径上,就应该默认呈现 JSON 响应,如以下示例所示:
-
Java
-
Kotlin
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
@RequestMapping("/thing")
public MyThing thing() {
return new MyThing();
}
}
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
@RestController
class MyController {
@RequestMapping("/thing")
fun thing(): MyThing {
return MyThing()
}
}
只要MyThing
可以由 Jackson2 序列化(对于普通的 POJO 或 Groovy 对象为 true),然后localhost:8080/thing
默认情况下,提供它的 JSON 表示形式。
请注意,在浏览器中,您有时可能会看到 XML 响应,因为浏览器倾向于发送首选 XML 的接受标头。
编写 XML REST 服务
如果您有 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 可用,则可以呈现 XML 并具有MyThing
注释为@XmlRootElement
,如以下示例所示:
-
Java
-
Kotlin
import jakarta.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class MyThing {
private String name;
// getters/setters ...
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
import jakarta.xml.bind.annotation.XmlRootElement
@XmlRootElement
class MyThing {
var name: String? = null
}
您需要确保 JAXB 库是项目的一部分,例如通过添加:
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
</dependency>
要让服务器呈现 XML 而不是 JSON,您可能需要发送Accept: text/xml 标头(或使用浏览器)。 |
自定义 Jackson ObjectMapper
Spring MVC(客户端和服务器端)使用HttpMessageConverters
在 HTTP 交换中协商内容转换。
如果 Jackson 在类路径上,则您已经获得了由Jackson2ObjectMapperBuilder
,其实例是自动配置的。
这ObjectMapper
(或XmlMapper
对于 Jackson XML 转换器)实例(默认创建)具有以下自定义属性:
-
MapperFeature.DEFAULT_VIEW_INCLUSION
已禁用 -
DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
已禁用 -
SerializationFeature.WRITE_DATES_AS_TIMESTAMPS
已禁用 -
SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS
已禁用
Spring Boot 还具有一些功能,可以更轻松地自定义此行为。
您可以配置ObjectMapper
和XmlMapper
实例。
Jackson 提供了一套广泛的开/关功能,可用于配置其处理的各个方面。
这些功能在几个枚举(在 Jackson 中)中进行了描述,这些枚举映射到环境中的属性:
枚举 | 属性 | 值 |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
例如,要启用漂亮打印,请将spring.jackson.serialization.indent_output=true
.
请注意,由于使用了宽松的绑定,因此indent_output
不必匹配相应枚举常量的大小写,即INDENT_OUTPUT
.
此基于环境的配置应用于自动配置的Jackson2ObjectMapperBuilder
bean 并适用于使用构建器创建的任何映射器,包括自动配置的ObjectMapper
豆。
上下文的Jackson2ObjectMapperBuilder
可由一个或多个定制Jackson2ObjectMapperBuilderCustomizer
豆。
可以对此类定制器 bean 进行排序(Boot 自己的定制器的顺序为 0),以便在 Boot 的自定义之前和之后应用额外的自定义。
任何类型的 beanModule
自动注册到自动配置的Jackson2ObjectMapperBuilder
并适用于任何ObjectMapper
它创建的实例。
这提供了一种全局机制,用于在向应用程序添加新功能时贡献自定义模块。
如果要替换默认值ObjectMapper
完全,要么定义一个@Bean
或者,如果您更喜欢基于构建器的方法,请定义一个Jackson2ObjectMapperBuilder
@Bean
.
定义ObjectMapper
bean,将其标记为@Primary
建议作为自动配置的ObjectMapper
它将取代@Primary
.
请注意,无论哪种情况,这样做都会禁用ObjectMapper
.
如果您提供任何@Beans
类型MappingJackson2HttpMessageConverter
,它们替换了 MVC 配置中的默认值。
另外,一种方便的豆子HttpMessageConverters
(如果您使用默认 MVC 配置,则始终可用)。
它有一些有用的方法来访问默认和用户增强的消息转换器。
请参阅自定义@ResponseBody渲染部分和WebMvcAutoConfiguration
源代码了解更多详情。
自定义@ResponseBody渲染
弹簧用途HttpMessageConverters
渲染@ResponseBody
(或来自@RestController
).
您可以通过在 Spring Boot 上下文中添加适当类型的 bean 来贡献其他转换器。
如果您添加的 bean 的类型无论如何都会被默认包含(例如MappingJackson2HttpMessageConverter
对于 JSON 转换),它会替换默认值。
一种方便的豆子HttpMessageConverters
提供,并且如果您使用默认 MVC 配置,则始终可用。
它有一些有用的方法来访问默认和用户增强的消息转换器(例如,如果您想将它们手动注入到自定义RestTemplate
).
与正常的 MVC 用法一样,任何WebMvcConfigurer
您提供的 bean 也可以通过覆盖configureMessageConverters
方法。
但是,与普通 MVC 不同的是,您只能提供所需的其他转换器(因为 Spring Boot 使用相同的机制来贡献其默认值)。
最后,如果您通过提供自己的@EnableWebMvc
配置,您可以完全控制并使用getMessageConverters
从WebMvcConfigurationSupport
.
请参阅WebMvcAutoConfiguration
源代码了解更多详情。
处理多部分文件上传
Spring Boot 采用 servlet 5Part
支持上传文件的 API。
默认情况下,Spring Boot 将 Spring MVC 配置为每个文件的最大大小为 1MB,单个请求中最多 10MB 的文件数据。
您可以覆盖这些值,即中间数据存储的位置(例如,到/tmp
目录),以及使用中公开的属性将数据刷新到磁盘的阈值MultipartProperties
类。
例如,如果要指定文件不受限制,请将spring.servlet.multipart.max-file-size
属性设置为-1
.
当您想要接收多部分编码的文件数据作为@RequestParam
-annotated 类型的参数MultipartFile
在 Spring MVC 控制器处理程序方法中。
请参阅MultipartAutoConfiguration
来源了解更多详情。
建议使用容器对分段上传的内置支持,而不是引入额外的依赖项,例如 Apache Commons 文件上传。 |
关闭 Spring MVC DispatcherServlet
默认情况下,所有内容都从应用程序的根目录 () 提供。
如果您希望映射到不同的路径,可以按如下方式配置一个路径:/
-
Properties
-
YAML
spring.mvc.servlet.path=/mypath
spring:
mvc:
servlet:
path: "/mypath"
如果你有其他 servlet,你可以声明一个@Bean
类型Servlet
或ServletRegistrationBean
对于每个,Spring Boot 会将它们透明地注册到容器中。
因为 servlet 是以这种方式注册的,所以它们可以映射到DispatcherServlet
而不调用它。
配置DispatcherServlet
你自己很不寻常,但如果你真的需要这样做,一个@Bean
类型DispatcherServletPath
还必须提供自定义的路径DispatcherServlet
.
关闭默认 MVC 配置
完全控制 MVC 配置的最简单方法是提供您自己的@Configuration
使用@EnableWebMvc
注解。 这样做将所有 MVC 配置都交给您。
自定义 ViewResolver
一个ViewResolver
是 Spring MVC 的核心组件,将视图名称翻译为@Controller
到实际View
实现。 请注意,视图解析器主要用于 UI 应用程序,而不是 REST 样式的服务(View
不用于渲染@ResponseBody
). 有很多实现ViewResolver
可供选择,并且 Spring 本身对您应该使用哪些并不固执己见。另一方面,Spring Boot 会为您安装一两个,具体取决于它在类路径和应用程序上下文中找到的内容。 这DispatcherServlet
使用它在应用程序上下文中找到的所有解析器,依次尝试每个解析器,直到得到结果。如果您添加自己的解析器,则必须了解解析器的添加顺序和位置。
WebMvcAutoConfiguration
添加以下内容ViewResolver
bean 到你的上下文:
-
一
InternalResourceViewResolver
名为 'defaultViewResolver' 的物理资源。这个定位物理资源可以通过使用DefaultServlet
(包括静态资源和 JSP 页面,如果您使用它们)。 它将前缀和后缀应用于视图名称,然后在 servlet 上下文中查找具有该路径的物理资源(默认值均为空,但可以通过外部配置访问spring.mvc.view.prefix
和spring.mvc.view.suffix
). 您可以通过提供相同类型的 bean 来覆盖它。 -
一个
BeanNameViewResolver
名为 'beanNameViewResolver'。这是视图解析器链的一个有用成员,它会选择与View
正在解决。没有必要覆盖或替换它。 -
一个
ContentNegotiatingViewResolver
仅当实际存在类型为View
目前。 这是一个复合解析器,委托给所有其他解析器并尝试找到与客户端发送的“Accept”HTTP 标头匹配的解析器。有一个有用的博客ContentNegotiatingViewResolver
您可能想研究以了解更多信息,并且还可以查看源代码以获取详细信息。您可以关闭自动配置的ContentNegotiatingViewResolver
通过定义一个名为“viewResolver”的 bean。 -
如果您使用百里叶烟,您还有一个
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
. 前缀和后缀的默认值分别为空和“.ftlh”。 您可以覆盖FreeMarkerViewResolver
通过提供同名的 bean。 FreeMarker 变量可以通过定义类型为FreeMarkerVariablesCustomizer
. -
如果您使用 Groovy 模板(实际上,如果
groovy-templates
在您的类路径上),您还有一个GroovyMarkupViewResolver
命名为 'groovyMarkupViewResolver'。 它通过用前缀和后缀(外部化为spring.groovy.template.prefix
和spring.groovy.template.suffix
). 前缀和后缀的默认值分别为 'classpath:/templates/' 和 '.tpl'。 您可以覆盖GroovyMarkupViewResolver
通过提供同名的 bean。 -
如果您使用 Mustache,您还有一个
MustacheViewResolver
名为 'mustacheViewResolver'。 它通过用前缀和后缀包围视图名称来查找资源。 前缀是spring.mustache.prefix
,后缀为spring.mustache.suffix
. 前缀和后缀的值分别默认为 'classpath:/templates/' 和 '.mustache'。 您可以覆盖MustacheViewResolver
通过提供同名的 bean。
有关更多详细信息,请参阅以下部分:
自定义“白标”错误页面
Spring Boot 会安装一个“白标”错误页面,如果遇到服务器错误,您将在浏览器客户端中看到该页面(使用 JSON 和其他媒体类型的机器客户端应该会看到带有正确错误代码的合理响应)。
设置server.error.whitelabel.enabled=false 以关闭默认错误页面。
这样做将恢复您正在使用的 servlet 容器的默认值。
请注意,Spring Boot 仍然会尝试解决错误视图,因此您可能应该添加自己的错误页面,而不是完全禁用它。 |
使用您自己的错误页面覆盖错误页面取决于您使用的模板技术。
例如,如果您使用 Thymeleaf,则可以添加error.html
模板。
如果您使用 FreeMarker,您可以添加一个error.ftlh
模板。
一般来说,您需要一个View
以名称error
或@Controller
处理/error
路径。
除非您替换了一些默认配置,否则您应该找到一个BeanNameViewResolver
在你的ApplicationContext
,所以一个@Bean
叫error
将是做到这一点的一种方法。
看ErrorMvcAutoConfiguration
以获取更多选择。
有关如何在 Servlet 容器中注册处理程序的详细信息,另请参阅错误处理部分。