Spring Boot 操作指南 Spring MVC Spring MVC Spring Boot 有许多包含 Spring MVC 的启动器。请注意,某些启动器包含对 Spring MVC 的依赖,而不是直接包含 Spring MVC。本节回答有关 Spring MVC 和 Spring Boot 的常见问题。 编写 JSON REST 服务 只要类路径中包含 Jackson2,Spring Boot 应用程序中的任何 Spring @RestController 都应默认呈现 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(或 Jackson XML 转换器的 XmlMapper)实例(默认创建)具有以下自定义属性 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 中),这些枚举映射到环境中的属性 枚举 属性 值 com.fasterxml.jackson.databind.cfg.EnumFeature spring.jackson.datatype.enum.<feature_name> true、false com.fasterxml.jackson.databind.cfg.JsonNodeFeature spring.jackson.datatype.json-node.<feature_name> true、false 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 自定义之前和之后应用其他自定义。 任何类型为 com.fasterxml.jackson.databind.Module 的 bean 都将自动注册到自动配置的 Jackson2ObjectMapperBuilder 中,并应用到它创建的任何 ObjectMapper 实例中。当向应用程序添加新功能时,这提供了一种全局机制来提供自定义模块。 如果你想完全替换默认的 ObjectMapper,请定义该类型的 @Bean 并将其标记为 @Primary,或者如果你更喜欢基于构建器的方法,请定义 Jackson2ObjectMapperBuilder @Bean。请注意,在这两种情况下,这样做都会禁用 ObjectMapper 的所有自动配置。 如果你提供了任何类型为 MappingJackson2HttpMessageConverter 的 @Beans,它们将替换 MVC 配置中的默认值。此外,还提供了类型为 HttpMessageConverters 的便利 bean(如果你使用默认 MVC 配置,它始终可用)。它有一些有用的方法来访问默认和用户增强型消息转换器。 请参阅“自定义 @ResponseBody 渲染”部分和 WebMvcAutoConfiguration 源代码以获取更多详细信息。 自定义 @ResponseBody 渲染 Spring 使用 HttpMessageConverters 来渲染 @ResponseBody(或来自 @RestController 的响应)。你可以通过在 Spring Boot 上下文中添加适当类型的 bean 来提供其他转换器。如果你添加的 bean 是默认情况下本应包含的类型(例如,用于 JSON 转换的 MappingJackson2HttpMessageConverter),它将替换默认值。提供了类型为 HttpMessageConverters 的便利 bean,如果你使用默认 MVC 配置,它始终可用。它有一些有用的方法来访问默认和用户增强型消息转换器(例如,如果你想将它们手动注入自定义 RestTemplate 中,这可能很有用)。 与常规 MVC 用法一样,您提供的任何 WebMvcConfigurer bean 也可以通过覆盖 configureMessageConverters 方法来提供转换器。但是,与常规 MVC 不同,您只能提供所需的附加转换器(因为 Spring Boot 使用相同的机制来提供其默认值)。最后,如果您通过提供自己的 @EnableWebMvc 配置选择退出 Spring Boot 默认 MVC 配置,则可以使用 WebMvcConfigurationSupport 中的 getMessageConverters 完全控制并手动执行所有操作。 有关更多详细信息,请参见 WebMvcAutoConfiguration 源代码。 处理多部分文件上传 Spring Boot 采用 servlet 5 jakarta.servlet.http.Part API 来支持上传文件。默认情况下,Spring Boot 使用每个文件最大 1MB 和单个请求中最多 10MB 文件数据配置 Spring MVC。您可以使用 MultipartProperties 类中公开的属性覆盖这些值、存储中间数据的位置(例如,到 /tmp 目录)以及将数据刷新到磁盘的阈值。例如,如果您想指定文件不受限制,请将 spring.servlet.multipart.max-file-size 属性设置为 -1。 当您想在 Spring MVC 控制器处理程序方法中接收多部分编码的文件数据作为 @RequestParam 注释的 MultipartFile 类型参数时,多部分支持非常有用。 有关更多详细信息,请参见 MultipartAutoConfiguration 源代码。 建议使用容器内置的多部分上传支持,而不是引入其他依赖项,例如 Apache Commons File Upload。 关闭 Spring MVC DispatcherServlet 默认情况下,所有内容都从应用程序的根目录 (/) 提供。如果您希望映射到其他路径,可以按如下方式配置一个 属性 YAML spring.mvc.servlet.path=/mypath spring: mvc: servlet: path: "/mypath" 如果您有其他 servlet,可以为每个 servlet 声明一个 Servlet 或 ServletRegistrationBean 类型的 @Bean,Spring Boot 会将它们透明地注册到容器中。由于 servlet 是以这种方式注册的,因此它们可以映射到 DispatcherServlet 的子上下文,而无需调用它。 自己配置 DispatcherServlet 并不常见,但如果您确实需要这样做,还必须提供 DispatcherServletPath 类型的 @Bean 来提供自定义 DispatcherServlet 的路径。 关闭默认 MVC 配置 完全控制 MVC 配置的最简单方法是使用带有 @EnableWebMvc 注解的 @Configuration 提供你自己的配置。这样做可以让你掌控所有 MVC 配置。 自定义视图解析器 ViewResolver 是 Spring MVC 的核心组件,它将 @Controller 中的视图名称转换为实际的 View 实现。请注意,ViewResolvers 主要用于 UI 应用程序,而不是 REST 风格的服务(View 不用于呈现 @ResponseBody)。有很多 ViewResolver 实现可供选择,Spring 本身不会对应该使用哪种实现发表意见。另一方面,Spring Boot 会根据在类路径和应用程序上下文中找到的内容为你安装一个或两个实现。DispatcherServlet 使用它在应用程序上下文中找到的所有解析器,依次尝试每个解析器,直到获得结果。如果你添加了自己的解析器,则必须注意解析器的顺序和添加位置。 WebMvcAutoConfiguration 向你的上下文中添加了以下 ViewResolvers 名为“defaultViewResolver”的 InternalResourceViewResolver。它找到可使用 DefaultServlet 呈现的物理资源(包括静态资源和 JSP 页面,如果你使用它们的话)。它将前缀和后缀应用于视图名称,然后在 servlet 上下文中查找具有该路径的物理资源(默认值均为空,但可以通过 spring.mvc.view.prefix 和 spring.mvc.view.suffix 进行外部配置)。你可以通过提供相同类型的 bean 来覆盖它。 名为“beanNameViewResolver”的 BeanNameViewResolver。这是视图解析器链中的一个有用成员,它会选取与要解析的 View 同名的任何 bean。无需覆盖或替换它。 仅在实际存在类型为 View 的 bean 时,才会添加名为“viewResolver”的 ContentNegotiatingViewResolver。这是一个复合解析器,它委托给所有其他解析器,并尝试找到与客户端发送的“Accept”HTTP 标头匹配的解析器。有一篇关于 ContentNegotiatingViewResolver 的有用 博客,你可能希望研究它以了解更多信息,你还可以查看源代码以了解详细信息。你可以通过定义名为“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。 有关更多详细信息,请参阅以下部分 WebMvcAutoConfiguration ThymeleafAutoConfiguration FreeMarkerAutoConfiguration GroovyTemplateAutoConfiguration 嵌入式 Web 服务器 Jersey