对于最新的稳定版本,请使用 Spring Boot 3.5.5spring-doc.cadn.net.cn

弹簧 MVC

Spring Boot 有许多Starters,其中包括 Spring MVC。 请注意,一些Starters包含对 Spring MVC 的依赖,而不是直接包含它。 本节回答有关 Spring MVC 和 Spring Boot 的常见问题。spring-doc.cadn.net.cn

编写 JSON REST 服务

任何弹簧@RestController在 Spring Boot 应用程序中,只要 Jackson2 在类路径上,就应该默认呈现 JSON 响应,如以下示例所示:spring-doc.cadn.net.cn

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 的接受标头。spring-doc.cadn.net.cn

编写 XML REST 服务

如果您有 Jackson XML 扩展 (jackson-dataformat-xml) 在类路径上,您可以使用它来呈现 XML 响应。 我们用于 JSON 的前面示例可以工作。 要使用 Jackson XML 渲染器,请向项目添加以下依赖项:spring-doc.cadn.net.cn

<dependency>
	<groupId>com.fasterxml.jackson.dataformat</groupId>
	<artifactId>jackson-dataformat-xml</artifactId>
</dependency>

如果 Jackson 的 XML 扩展不可用,而 JAXB 可用,则可以呈现 XML 并具有MyThing注释为@XmlRootElement,如以下示例所示:spring-doc.cadn.net.cn

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 库是项目的一部分,例如通过添加:spring-doc.cadn.net.cn

<dependency>
	<groupId>org.glassfish.jaxb</groupId>
	<artifactId>jaxb-runtime</artifactId>
</dependency>
要让服务器呈现 XML 而不是 JSON,您可能需要发送Accept: text/xml标头(或使用浏览器)。

自定义 Jackson ObjectMapper

Spring MVC(客户端和服务器端)使用HttpMessageConverters在 HTTP 交换中协商内容转换。 如果 Jackson 在类路径上,则您已经获得了由Jackson2ObjectMapperBuilder,其实例是自动配置的。spring-doc.cadn.net.cn

ObjectMapper(或XmlMapper对于 Jackson XML 转换器)实例(默认创建)具有以下自定义属性:spring-doc.cadn.net.cn

Spring Boot 还具有一些功能,可以更轻松地自定义此行为。spring-doc.cadn.net.cn

您可以配置ObjectMapperXmlMapper实例。 Jackson 提供了一套广泛的开/关功能,可用于配置其处理的各个方面。 这些功能在几个枚举(在 Jackson 中)中进行了描述,这些枚举映射到环境中的属性:spring-doc.cadn.net.cn

枚举 属性

EnumFeaturespring-doc.cadn.net.cn

spring.jackson.datatype.enum.<feature_name>spring-doc.cadn.net.cn

true,falsespring-doc.cadn.net.cn

JsonNodeFeaturespring-doc.cadn.net.cn

spring.jackson.datatype.json-node.<feature_name>spring-doc.cadn.net.cn

true,falsespring-doc.cadn.net.cn

DeserializationFeaturespring-doc.cadn.net.cn

spring.jackson.deserialization.<feature_name>spring-doc.cadn.net.cn

true,falsespring-doc.cadn.net.cn

JsonGenerator.Featurespring-doc.cadn.net.cn

spring.jackson.generator.<feature_name>spring-doc.cadn.net.cn

true,falsespring-doc.cadn.net.cn

MapperFeaturespring-doc.cadn.net.cn

spring.jackson.mapper.<feature_name>spring-doc.cadn.net.cn

true,falsespring-doc.cadn.net.cn

JsonParser.Featurespring-doc.cadn.net.cn

spring.jackson.parser.<feature_name>spring-doc.cadn.net.cn

true,falsespring-doc.cadn.net.cn

SerializationFeaturespring-doc.cadn.net.cn

spring.jackson.serialization.<feature_name>spring-doc.cadn.net.cn

true,falsespring-doc.cadn.net.cn

JsonInclude.Includespring-doc.cadn.net.cn

spring.jackson.default-property-inclusionspring-doc.cadn.net.cn

always,non_null,non_absent,non_default,non_emptyspring-doc.cadn.net.cn

例如,要启用漂亮打印,请将spring.jackson.serialization.indent_output=true. 请注意,由于使用了宽松的绑定,因此indent_output不必匹配相应枚举常量的大小写,即INDENT_OUTPUT.spring-doc.cadn.net.cn

此基于环境的配置应用于自动配置的Jackson2ObjectMapperBuilderbean 并适用于使用构建器创建的任何映射器,包括自动配置的ObjectMapper豆。spring-doc.cadn.net.cn

上下文的Jackson2ObjectMapperBuilder可由一个或多个定制Jackson2ObjectMapperBuilderCustomizer豆。 可以对此类定制器 bean 进行排序(Boot 自己的定制器的顺序为 0),以便在 Boot 的自定义之前和之后应用额外的自定义。spring-doc.cadn.net.cn

任何类型的 beanModule自动注册到自动配置的Jackson2ObjectMapperBuilder并适用于任何ObjectMapper它创建的实例。 这提供了一种全局机制,用于在向应用程序添加新功能时贡献自定义模块。spring-doc.cadn.net.cn

如果要替换默认值ObjectMapper完全,要么定义一个@Bean或者,如果您更喜欢基于构建器的方法,请定义一个Jackson2ObjectMapperBuilder @Bean. 定义ObjectMapperbean,将其标记为@Primary建议作为自动配置的ObjectMapper它将取代@Primary. 请注意,无论哪种情况,这样做都会禁用ObjectMapper.spring-doc.cadn.net.cn

如果您提供任何@Beans类型MappingJackson2HttpMessageConverter,它们替换了 MVC 配置中的默认值。 另外,一种方便的豆子HttpMessageConverters(如果您使用默认 MVC 配置,则始终可用)。 它有一些有用的方法来访问默认和用户增强的消息转换器。spring-doc.cadn.net.cn

请参阅自定义@ResponseBody渲染部分和WebMvcAutoConfiguration源代码了解更多详情。spring-doc.cadn.net.cn

自定义@ResponseBody渲染

弹簧用途HttpMessageConverters渲染@ResponseBody(或来自@RestController). 您可以通过在 Spring Boot 上下文中添加适当类型的 bean 来贡献其他转换器。 如果您添加的 bean 的类型无论如何都会被默认包含(例如MappingJackson2HttpMessageConverter对于 JSON 转换),它会替换默认值。 一种方便的豆子HttpMessageConverters提供,并且如果您使用默认 MVC 配置,则始终可用。 它有一些有用的方法来访问默认和用户增强的消息转换器(例如,如果您想将它们手动注入到自定义RestTemplate).spring-doc.cadn.net.cn

与正常的 MVC 用法一样,任何WebMvcConfigurer您提供的 bean 也可以通过覆盖configureMessageConverters方法。 但是,与普通 MVC 不同的是,您只能提供所需的其他转换器(因为 Spring Boot 使用相同的机制来贡献其默认值)。 最后,如果您通过提供自己的@EnableWebMvc配置,您可以完全控制并使用getMessageConvertersWebMvcConfigurationSupport.spring-doc.cadn.net.cn

请参阅WebMvcAutoConfiguration源代码了解更多详情。spring-doc.cadn.net.cn

处理多部分文件上传

Spring Boot 采用 servlet 5Part支持上传文件的 API。 默认情况下,Spring Boot 将 Spring MVC 配置为每个文件的最大大小为 1MB,单个请求中最多 10MB 的文件数据。 您可以覆盖这些值,即中间数据存储的位置(例如,到/tmp目录),以及使用中公开的属性将数据刷新到磁盘的阈值MultipartProperties类。 例如,如果要指定文件不受限制,请将spring.servlet.multipart.max-file-size属性设置为-1.spring-doc.cadn.net.cn

当您想要接收多部分编码的文件数据作为@RequestParam-annotated 类型的参数MultipartFile在 Spring MVC 控制器处理程序方法中。spring-doc.cadn.net.cn

请参阅MultipartAutoConfiguration来源了解更多详情。spring-doc.cadn.net.cn

建议使用容器对分段上传的内置支持,而不是引入额外的依赖项,例如 Apache Commons 文件上传。

关闭 Spring MVC DispatcherServlet

默认情况下,所有内容都从应用程序的根目录 () 提供。 如果您希望映射到不同的路径,可以按如下方式配置一个路径:/spring-doc.cadn.net.cn

spring.mvc.servlet.path=/mypath
spring:
  mvc:
    servlet:
      path: "/mypath"

如果你有其他 servlet,你可以声明一个@Bean类型ServletServletRegistrationBean对于每个,Spring Boot 会将它们透明地注册到容器中。 因为 servlet 是以这种方式注册的,所以它们可以映射到DispatcherServlet而不调用它。spring-doc.cadn.net.cn

配置DispatcherServlet你自己很不寻常,但如果你真的需要这样做,一个@Bean类型DispatcherServletPath还必须提供自定义的路径DispatcherServlet.spring-doc.cadn.net.cn

关闭默认 MVC 配置

完全控制 MVC 配置的最简单方法是提供您自己的@Configuration使用@EnableWebMvc注解。 这样做将所有 MVC 配置都交给您。spring-doc.cadn.net.cn

自定义 ViewResolver

一个ViewResolver是 Spring MVC 的核心组件,将视图名称翻译为@Controller到实际View实现。 请注意,视图解析器主要用于 UI 应用程序,而不是 REST 样式的服务(View不用于渲染@ResponseBody). 有很多实现ViewResolver可供选择,并且 Spring 本身对您应该使用哪些并不固执己见。另一方面,Spring Boot 会为您安装一两个,具体取决于它在类路径和应用程序上下文中找到的内容。 这DispatcherServlet使用它在应用程序上下文中找到的所有解析器,依次尝试每个解析器,直到得到结果。如果您添加自己的解析器,则必须了解解析器的添加顺序和位置。spring-doc.cadn.net.cn

WebMvcAutoConfiguration添加以下内容ViewResolverbean 到你的上下文:spring-doc.cadn.net.cn

  • InternalResourceViewResolver名为 'defaultViewResolver' 的物理资源。这个定位物理资源可以通过使用DefaultServlet(包括静态资源和 JSP 页面,如果您使用它们)。 它将前缀和后缀应用于视图名称,然后在 servlet 上下文中查找具有该路径的物理资源(默认值均为空,但可以通过外部配置访问spring.mvc.view.prefixspring.mvc.view.suffix). 您可以通过提供相同类型的 bean 来覆盖它。spring-doc.cadn.net.cn

  • 一个BeanNameViewResolver名为 'beanNameViewResolver'。这是视图解析器链的一个有用成员,它会选择与View正在解决。没有必要覆盖或替换它。spring-doc.cadn.net.cn

  • 一个ContentNegotiatingViewResolver仅当实际存在类型为View目前。 这是一个复合解析器,委托给所有其他解析器并尝试找到与客户端发送的“Accept”HTTP 标头匹配的解析器。有一个有用的博客 ContentNegotiatingViewResolver您可能想研究以了解更多信息,并且还可以查看源代码以获取详细信息。您可以关闭自动配置的ContentNegotiatingViewResolver通过定义一个名为“viewResolver”的 bean。spring-doc.cadn.net.cn

  • 如果您使用百里叶烟,您还有一个ThymeleafViewResolver命名为“thymeleafViewResolver”。 它通过用前缀和后缀包围视图名称来查找资源。 前缀是spring.thymeleaf.prefix,后缀为spring.thymeleaf.suffix. 前缀和后缀的值分别默认为 'classpath:/templates/' 和 '.html'。 您可以覆盖ThymeleafViewResolver通过提供同名的 bean。spring-doc.cadn.net.cn

  • 如果您使用 FreeMarker,您还有一个FreeMarkerViewResolver名为 'freeMarkerViewResolver'。 它在加载器路径中查找资源(外部化为spring.freemarker.templateLoaderPath并且默认值为 'classpath:/templates/'),方法是用前缀和后缀将视图名称括起来。 前缀被外部化为spring.freemarker.prefix,后缀被外部化为spring.freemarker.suffix. 前缀和后缀的默认值分别为空和“.ftlh”。 您可以覆盖FreeMarkerViewResolver通过提供同名的 bean。 FreeMarker 变量可以通过定义类型为FreeMarkerVariablesCustomizer.spring-doc.cadn.net.cn

  • 如果您使用 Groovy 模板(实际上,如果groovy-templates在您的类路径上),您还有一个GroovyMarkupViewResolver命名为 'groovyMarkupViewResolver'。 它通过用前缀和后缀(外部化为spring.groovy.template.prefixspring.groovy.template.suffix). 前缀和后缀的默认值分别为 'classpath:/templates/' 和 '.tpl'。 您可以覆盖GroovyMarkupViewResolver通过提供同名的 bean。spring-doc.cadn.net.cn

  • 如果您使用 Mustache,您还有一个MustacheViewResolver名为 'mustacheViewResolver'。 它通过用前缀和后缀包围视图名称来查找资源。 前缀是spring.mustache.prefix,后缀为spring.mustache.suffix. 前缀和后缀的值分别默认为 'classpath:/templates/' 和 '.mustache'。 您可以覆盖MustacheViewResolver通过提供同名的 bean。spring-doc.cadn.net.cn

有关更多详细信息,请参阅以下部分:spring-doc.cadn.net.cn

自定义“白标”错误页面

Spring Boot 会安装一个“白标”错误页面,如果遇到服务器错误,您将在浏览器客户端中看到该页面(使用 JSON 和其他媒体类型的机器客户端应该会看到带有正确错误代码的合理响应)。spring-doc.cadn.net.cn

设置server.error.whitelabel.enabled=false以关闭默认错误页面。 这样做将恢复您正在使用的 servlet 容器的默认值。 请注意,Spring Boot 仍然会尝试解决错误视图,因此您可能应该添加自己的错误页面,而不是完全禁用它。

使用您自己的错误页面覆盖错误页面取决于您使用的模板技术。 例如,如果您使用 Thymeleaf,则可以添加error.html模板。 如果您使用 FreeMarker,您可以添加一个error.ftlh模板。 一般来说,您需要一个View以名称error@Controller处理/error路径。 除非您替换了一些默认配置,否则您应该找到一个BeanNameViewResolver在你的ApplicationContext,所以一个@Beanerror将是做到这一点的一种方法。 看ErrorMvcAutoConfiguration以获取更多选择。spring-doc.cadn.net.cn

有关如何在 Servlet 容器中注册处理程序的详细信息,另请参阅错误处理部分。spring-doc.cadn.net.cn