28.1.1 Spring MVC自动配置
Spring Boot为Spring MVC提供了自动配置,适用于大多数应用程序。
自动配置在Spring的默认值之上添加了以下功能:
包含 ContentNegotiatingViewResolver 和 BeanNameViewResolver beans。
支持提供静态资源,包括对WebJars的支持( 本文档稍后介绍))。
自动注册 Converter , GenericConverter 和 Formatter beans。
支持 HttpMessageConverters ( 本文档稍后部分)。
自动注册 MessageCodesResolver ( 本文档后面部分)。
静态 index.html 支持。
自定义 Favicon 支持(本文档稍后介绍)。
自动使用 ConfigurableWebBindingInitializer bean(本文 后面会介绍)。
如果你想保留Spring Boot MVC功能,并且你想添加额外的 MVC配置(拦截器,格式化程序,视图控制器和其他功能),你可以添加自己
的 @Configuration 类 WebMvcConfigurer 类但没有 @EnableWebMvc 。如果您希望提
供 RequestMappingHandlerMapping , RequestMappingHandlerAdapter 或 ExceptionHandlerExceptionResolver 的自定义实例,则可以
声明 WebMvcRegistrationsAdapter 实例以提供此类组件。
如果您想完全控制Spring MVC,可以添加自己的 @Configuration 注释 @EnableWebMvc 。
28.1.2 HttpMessageConverters
Spring MVC使用 HttpMessageConverter 接口转换HTTP请求和响应。明智的默认设置包含在开箱即用中。例如,对象可以自动转换为JSON
(通过使用Jackson库)或XML(如果可用,使用Jackson XML扩展,或者如果Jackson XML扩展不是,则使用JAXB可用)。默认情况下,字
符串以 UTF-8 编码。
如果您需要添加或自定义转换器,可以使用Spring Boot的 HttpMessageConverters 类,如下面的清单所示:
import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
import org.springframework.context.annotation.*;
import org.springframework.http.converter.*;
@Configuration
public class MyConfiguration {
@Bean
public HttpMessageConverters customConverters() {
HttpMessageConverter<?> additional = ...
HttpMessageConverter<?> another = ...
return new HttpMessageConverters(additional, another);
}
}
上下文中存在的任何 HttpMessageConverter bean都将添加到转换器列表中。您也可以以相同的方式覆盖默认转换器。
28.1.3自定义JSON序列化程序和反序列化程序
如果使用Jackson序列化和反序列化JSON数据,您可能需要编写自己的 JsonSerializer 和 JsonDeserializer 类。自定义序列化程序通常 通
过模块注册Jackson,但Spring Boot提供了另一种 @JsonComponent 注释,可以更容易地直接注册Spring Beans。
您可以直接在 JsonSerializer 或 JsonDeserializer 实现上使用 @JsonComponent 注释。您还可以在包含序列化程序/反序列化程序作为内部
类的类上使用它,如以下示例所示:
import java.io.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import org.springframework.boot.jackson.*;
@JsonComponent
public class Example {
public static class Serializer extends JsonSerializer<SomeObject> {
// ...
}
public static class Deserializer extends JsonDeserializer<SomeObject> {
// ...
}
}
ApplicationContext 中的所有 @JsonComponent beans都会自动注册到Jackson。由于 @JsonComponent 使用 @Component 进行元注释,因
此通常的组件扫描规则适用。
Spring Boot还提供 JsonObjectSerializer 与 JsonObjectDeserializer 该给标准提供有用的替代基类Jackson版本序列化对象时。见
JsonObjectSerializer 和 JsonObjectDeserializer 在Javadoc了解详情。
28.1.4 MessageCodesResolver
Spring MVC有一个生成错误代码的策略,用于从绑定错误中呈现错误消息:MessageCodesResolver 。如果设
置 spring.mvc.message-codes-resolver.format 属性 PREFIX_ERROR_CODE 或 POSTFIX_ERROR_CODE ,则Spring Boot会为您创建一个(请
参阅枚举 DefaultMessageCodesResolver.Format )。
28.1.5静态内容
默认情况下,Spring Boot从类路径中的 /static (或 /public 或 /resources 或 /META-INF/resources )目录或 ServletContext 的根目
录中提供静态内容。它使用来自Spring MVC的 ResourceHttpRequestHandler ,以便您可以通过添加自己的 WebMvcConfigurer 并覆
盖 addResourceHandlers 方法来修改该行为。
在独立的Web应用程序中,容器中的默认servlet也会启用,并作为后备,如果Spring决定不处理它,则从 ServletContext 的根目录提供内
容。大多数情况下,这不会发生(除非您修改默认的MVC配置),因为Spring始终可以通过 DispatcherServlet 处理请求。
默认情况下,资源映射到 /** ,但您可以使用 spring.mvc.static-path-pattern 属性对其进行调整。例如,将所有资源重新定位
到 /resources/** 可以实现如下:
spring.mvc.static-path-pattern=/resources/**
您还可以使用 spring.resources.static-locations 属性自定义静态资源位置(将默认值替换为目录位置列表)。根Servlet上下文路
径 "/" 也会自动添加为位置。
除了前面提到的“标准”静态资源位置之外,还为Webjars内容制作了一个特例。如果它们以Webjars格式打包,那么具有 /webjars/** 中路径
的任何资源都将从jar文件中提供。
如果您的应用程序打包为jar,请不要使用 src/main/webapp 目录。虽然这个目录是一个通用的标准,它的工作原理只是战争的
包装,它是默默大多数构建工具忽略,如果你生成一个罐子。
Spring Boot还支持Spring MVC提供的高级资源处理功能,允许使用缓存破坏静态资源等用例或使用与Webjars无关的URL。
要为Webjars使用版本无关的URL,请添加 webjars-locator-core 依赖项。然后声明你的Webjar。以jQuery为例,添
加 "/webjars/jquery/jquery.min.js" 会产生 "/webjars/jquery/x.y.z/jquery.min.js" 。其中 x.y.z 是Webjar版本。
如果使用JBoss,则需要声明 webjars-locator-jboss-vfs 依赖项而不是 webjars-locator-core 。否则,所有Webjars都将解
析为 404 。
要使用缓存清除,以下配置会为所有静态资源配置缓存清除解决方案,从而在URL中有效添加内容哈希(例
如 <link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/> ):
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
由于为Thymeleaf和FreeMarker自动配置了 ResourceUrlEncodingFilter ,因此在运行时可以在模板中重写资源链接。您应该
在使用JSP时手动声明此过滤器。其他模板引擎目前不是自动支持的,但可以使用自定义模板宏/帮助程序和使用
ResourceUrlProvider 。
使用(例如)JavaScript模块加载器动态加载资源时,不能重命名文件。这就是为什么其他策略也得到支持并可以合并的原因。“固定”策略在
URL中添加静态版本字符串而不更改文件名,如以下示例所示:
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
spring.resources.chain.strategy.fixed.enabled=true
spring.resources.chain.strategy.fixed.paths=/js/lib/
spring.resources.chain.strategy.fixed.version=v12
使用此配置,位于 "/js/lib/" 下的JavaScript模块使用固定版本控制策略( "/v12/js/lib/mymodule.js" ),而其他资源仍使用内容1
( <link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/> )。
有关 ResourceProperties 更多支持选项,请参阅
此功能已在专门的博客文章和Spring Framework的 参考文档中进行了详细描述 。
28.1.6欢迎页面
Spring Boot支持静态和模板化的欢迎页面。它首先在配置的静态内容位置中查找 index.html 文件。如果找不到,则会查找 index 模板。如果
找到任何一个,它将自动用作应用程序的欢迎页面。
28.1.7自定义Favicon
Spring Boot在配置的静态内容位置和类路径的根(按此顺序)中查找 favicon.ico 。如果存在这样的文件,它将自动用作应用程序的
favicon。
28.1.8路径匹配和内容协商
Spring MVC可以通过查看请求路径并将其与应用程序中定义的映射相匹配(例如,关于Controller方法的 @GetMapping 注释),将传入的
HTTP请求映射到处理程序。
Spring Boot默认情况下选择禁用后缀模式匹配,这意味着像 "GET /projects/spring-boot.json" 这样的请求将不会
与 @GetMapping("/projects/spring-boot") 映射匹配。这被认为是Spring MVC应用程序的 最佳实践。对于没有发送正确“接受”请求标头
的HTTP客户端,此功能在过去主要有用; 我们需要确保将正确的内容类型发送给客户端。如今,内容协商更加可靠。
还有其他方法可以处理不一致发送正确“接受”请求标头的HTTP客户端。我们可以使用查询参数来确
保 "GET /projects/spring-boot?format=json" 之类的请求映射到 @GetMapping("/projects/spring-boot") ,而不是使用后缀匹配:
spring.mvc.contentnegotiation.favor-parameter=true
# We can change the parameter name, which is "format" by default:
# spring.mvc.contentnegotiation.parameter-name=myparam
# We can also register additional file extensions/media types with:
spring.mvc.contentnegotiation.media-types.markdown=text/markdown
如果您了解警告并仍希望您的应用程序使用后缀模式匹配,则需要以下配置:
spring.mvc.contentnegotiation.favor-path-extension=true
spring.mvc.pathmatch.use-suffix-pattern=true
或者,不是打开所有后缀模式,而是仅支持已注册的后缀模式更安全:
spring.mvc.contentnegotiation.favor-path-extension=true
spring.mvc.pathmatch.use-registered-suffix-pattern=true
# You can also register additional file extensions/media types with:
# spring.mvc.contentnegotiation.media-types.adoc=text/asciidoc