Appearance
Spring Web Servlet:MVC - Part5
Tip:基于 Spring Core 5.3.30 版本。
1. MVC 配置
MVC Java 配置和 MVC XML 命名空间为大多数应用程序提供了默认配置,并提供了一个配置 API 来进行自定义。
对于在配置 API 中无法实现的更高级的自定义,请参见高级 Java 配置和高级 XML 配置。
你不需要理解由 MVC Java 配置和 MVC 命名空间创建的底层 Bean。如果你想了解更多,请参见特殊的 Bean 类型和 Web MVC 配置。
1.1. 启用 MVC 配置
在 Java 配置中,你可以使用 @EnableWebMvc 注解来启用 MVC 配置,如下面的示例所示:
Java
@Configuration
@EnableWebMvc
public class WebConfig {
}1
2
3
4
2
3
4
在 XML 配置中,你可以使用 <mvc:annotation-driven> 元素来启用 MVC 配置,如下面的示例所示:
XML
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:annotation-driven/>
</beans>1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
前面的示例注册了一些 Spring MVC 基础设施 Bean,并根据类路径上可用的依赖进行了适配(例如,用于 JSON、XML 等的有效负载转换器)。
1.2. MVC 配置 API
在 Java 配置中,你可以实现 WebMvcConfigurer 接口,如下面的示例所示:
Java
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
// Implement configuration methods...
}1
2
3
4
5
2
3
4
5
在 XML 中,你可以检查 <mvc:annotation-driven/> 的属性和子元素。你可以查看 Spring MVC XML 架构,或者使用你的 IDE 的代码补全功能来发现可用的属性和子元素。
1.3. 类型转换
默认情况下,已经安装了各种数字和日期类型的格式化器,并且支持通过字段上的 @NumberFormat 和 @DateTimeFormat 进行自定义。
要在 Java 配置中注册自定义格式化器和转换器,请使用以下方法:
Java
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
// ...
}
}1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
要在 XML 配置中做同样的事情,请使用以下方法:
XML
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:annotation-driven conversion-service="conversionService"/>
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="org.example.MyConverter"/>
</set>
</property>
<property name="formatters">
<set>
<bean class="org.example.MyFormatter"/>
<bean class="org.example.MyAnnotationFormatterFactory"/>
</set>
</property>
<property name="formatterRegistrars">
<set>
<bean class="org.example.MyFormatterRegistrar"/>
</set>
</property>
</bean>
</beans>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
默认情况下,Spring MVC 在解析和格式化日期值时会考虑请求的 Locale。这适用于日期以 input 表单字段的字符串形式表示的表单。然而,对于 date 和 time 表单字段,浏览器使用 HTML 规范中定义的固定格式。对于这种情况,日期和时间的格式化可以按照以下方式自定义:
Java
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
registrar.setUseIsoFormat(true);
registrar.registerFormatters(registry);
}
}1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
Note:有关何时使用
FormatterRegistrar实现的更多信息,请参见FormatterRegistrarSPI 和FormattingConversionServiceFactoryBean。
1.4. 验证
默认情况下,如果 Bean 验证存在于类路径上(例如,Hibernate 验证器),则 LocalValidatorFactoryBean 会被注册为全局验证器,用于与控制器方法参数上的 @Valid 和 Validated 一起使用。
在 Java 配置中,你可以自定义全局 Validator 实例,如下面的示例所示:
Java
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public Validator getValidator() {
// ...
}
}1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
以下示例展示了如何在 XML 中实现相同的配置:
XML
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:annotation-driven validator="globalValidator"/>
</beans>1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
请注意,你也可以在本地注册 Validator 实现,如下面的示例所示:
Java
@Controller
public class MyController {
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.addValidators(new FooValidator());
}
}1
2
3
4
5
6
7
2
3
4
5
6
7
Note:如果你需要在某处注入
LocalValidatorFactoryBean,请创建一个 Bean 并用@Primary标记它,以避免与 MVC 配置中声明的那个产生冲突。
1.5. 拦截器
在 Java 配置中,你可以注册拦截器以应用于传入的请求,如下面的示例所示:
Java
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LocaleChangeInterceptor());
registry.addInterceptor(new ThemeChangeInterceptor()).addPathPatterns("/**").excludePathPatterns("/admin/**");
}
}1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
以下示例展示了如何在 XML 中实现相同的配置:
XML
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/admin/**"/>
<bean class="org.springframework.web.servlet.theme.ThemeChangeInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
Note:映射的拦截器并不是理想的安全层,因为它可能与带注解的控制器路径匹配存在不匹配的可能性,这也可以透明地匹配尾部斜线和路径扩展,以及其他路径匹配选项。许多这些选项已经被弃用,但不匹配的可能性仍然存在。一般来说,我们建议使用 Spring Security,它包含一个专用的
MvcRequestMatcher以与 Spring MVC 路径匹配对齐,同时还有一个安全防火墙,可以阻止 URL 路径中的许多不需要的字符。
1.6. 内容类型
你可以配置 Spring MVC 如何从请求中确定请求的媒体类型(例如,Accept 头,URL 路径扩展,查询参数等)。
默认情况下,只检查 Accept 头。
如果你必须使用基于 URL 的内容类型解析,请考虑使用查询参数策略而不是路径扩展。有关更多详细信息,请参见后缀匹配和后缀匹配与 RFD。
在 Java 配置中,你可以自定义请求的内容类型解析,如下面的示例所示:
Java
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.mediaType("json", MediaType.APPLICATION_JSON);
configurer.mediaType("xml", MediaType.APPLICATION_XML);
}
}1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
以下示例展示了如何在 XML 中实现相同的配置:
XML
<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager"/>
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="mediaTypes">
<value>
json=application/json
xml=application/xml
</value>
</property>
</bean>1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
1.7. 消息转换器
你可以通过覆盖 configureMessageConverters()(用于替换 Spring MVC 创建的默认转换器)或覆盖 extendMessageConverters()(用于自定义默认转换器或向默认转换器添加额外的转换器)在 Java 配置中自定义 HttpMessageConverter。
以下示例添加了 XML 和 Jackson JSON 转换器,并使用自定义的 ObjectMapper 替代了默认的转换器:
Java
@Configuration
@EnableWebMvc
public class WebConfiguration implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder()
.indentOutput(true)
.dateFormat(new SimpleDateFormat("yyyy-MM-dd"))
.modulesToInstall(new ParameterNamesModule());
converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
converters.add(new MappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true).build()));
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
在前面的示例中,使用 Jackson2ObjectMapperBuilder 为 MappingJackson2HttpMessageConverter 和 MappingJackson2XmlHttpMessageConverter 创建了一个通用的配置,启用了缩进,自定义了日期格式,并注册了 jackson-module-parameter-names,它增加了对访问参数名称的支持(这是 Java 8 中添加的功能)。
此构建器按如下方式自定义了 Jackson 的默认属性:
如果在类路径上检测到以下众所周知的模块,它也会自动注册:
jackson-datatype-joda:支持 Joda-Time 类型;jackson-datatype-jsr310:支持 Java 8 日期和时间 API 类型;jackson-datatype-jdk8:支持其他 Java 8 类型,如Optional;jackson-module-kotlin:支持 Kotlin 类和数据类;
Note:启用 Jackson XML 支持的缩进,除了
jackson-dataformat-xml之外,还需要woodstox-core-asl依赖。
还有其他有趣的 Jackson 模块可用:
jackson-datatype-money:支持javax.money类型(非官方模块);jackson-datatype-hibernate:支持 Hibernate 特定的类型和属性(包括懒加载方面);
以下示例展示了如何在 XML 中实现相同的配置:
XML
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper" ref="objectMapper"/>
</bean>
<bean class="org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter">
<property name="objectMapper" ref="xmlMapper"/>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<bean id="objectMapper" class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"
p:indentOutput="true"
p:simpleDateFormat="yyyy-MM-dd"
p:modulesToInstall="com.fasterxml.jackson.module.paramnames.ParameterNamesModule"/>
<bean id="xmlMapper" parent="objectMapper" p:createXmlMapper="true"/>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1.8. 视图控制器
这是定义 ParameterizableViewController 的快捷方式,当被调用时,它会立即转发到一个视图。在没有 Java 控制器逻辑在视图生成响应之前运行的静态情况下,你可以使用它。
以下 Java 配置的示例将对 / 的请求转发到一个名为 home 的视图:
Java
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("home");
}
}1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
以下示例通过使用 <mvc:view-controller> 元素,用 XML 实现了与前面的示例相同的功能:
XML
<mvc:view-controller path="/" view-name="home"/>如果一个 @RequestMapping 方法被映射到任何 HTTP 方法的 URL,那么视图控制器就不能用来处理同一个 URL。这是因为,URL 与带注解的控制器的匹配被认为是端点所有权的强烈指示,因此可以向客户端发送 405(METHOD_NOT_ALLOWED)、415(UNSUPPORTED_MEDIA_TYPE)或类似的响应,以帮助调试。因此,建议避免在带注解的控制器和视图控制器之间分割 URL 处理。
1.9. 视图解析器
MVC 配置简化了视图解析器的注册。
以下 Java 配置示例通过使用 JSP 和 Jackson 作为默认的 JSON 渲染视图,配置了内容协商视图解析:
Java
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.enableContentNegotiation(new MappingJackson2JsonView());
registry.jsp();
}
}1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
以下示例展示了如何在 XML 中实现相同的配置:
XML
<mvc:view-resolvers>
<mvc:content-negotiation>
<mvc:default-views>
<bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>
</mvc:default-views>
</mvc:content-negotiation>
<mvc:jsp/>
</mvc:view-resolvers>1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
然而,请注意,FreeMarker、Tiles、Groovy Markup 和脚本模板也需要配置底层的视图技术。
MVC 命名空间提供了专用元素。以下示例适用于 FreeMarker:
XML
<mvc:view-resolvers>
<mvc:content-negotiation>
<mvc:default-views>
<bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>
</mvc:default-views>
</mvc:content-negotiation>
<mvc:freemarker cache="false"/>
</mvc:view-resolvers>
<mvc:freemarker-configurer>
<mvc:template-loader-path location="/freemarker"/>
</mvc:freemarker-configurer>1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
在 Java 配置中,你可以添加相应的 Configurer Bean,如下面的示例所示:
Java
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.enableContentNegotiation(new MappingJackson2JsonView());
registry.freeMarker().cache(false);
}
@Bean
public FreeMarkerConfigurer freeMarkerConfigurer() {
FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
configurer.setTemplateLoaderPath("/freemarker");
return configurer;
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1.10. 静态资源
这个选项提供了一种方便的方式,可以从基于 Resource 的位置列表中提供静态资源。
在下一个示例中,给定一个以 /resources 开始的请求,相对路径被用来查找和提供相对于 Web 应用程序根目录下的 /public 或者类路径下的 /static 的静态资源。这些资源被设置为一年后过期,以确保最大限度地利用浏览器缓存,并减少浏览器发出的 HTTP 请求。最后修改信息是从 Resource#lastModified 中推断出来的,以便支持带有 Last-Modified 头的 HTTP 条件请求。
下面的列表展示了如何使用 Java 配置来实现这一点:
Java
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/public", "classpath:/static/")
.setCacheControl(CacheControl.maxAge(Duration.ofDays(365)));
}
}1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
以下示例展示了如何在 XML 中实现相同的配置:
XML
<mvc:resources mapping="/resources/**"
location="/public, classpath:/static/"
cache-period="31556926" />1
2
3
2
3
另请参阅静态资源的 HTTP 缓存支持。
资源处理器还支持一系列的 ResourceResolver 实现和 ResourceTransformer 实现,您可以使用它们来创建一个用于处理优化资源的工具链。
您可以使用 VersionResourceResolver 来基于从内容计算出的 MD5 哈希、固定的应用版本或其他方式来创建版本化的资源 URL。ContentVersionStrategy(MD5 哈希)是一个不错的选择 —— 尽管有一些值得注意的例外,比如与模块加载器一起使用的 JavaScript 资源。
以下示例展示了如何在 Java 配置中使用 VersionResourceResolver:
Java
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/public/")
.resourceChain(true)
.addResolver(new VersionResourceResolver().addContentVersionStrategy("/**"));
}
}1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
以下示例展示了如何在 XML 中实现相同的配置:
XML
<mvc:resources mapping="/resources/**" location="/public/">
<mvc:resource-chain resource-cache="true">
<mvc:resolvers>
<mvc:version-resolver>
<mvc:content-version-strategy patterns="/**"/>
</mvc:version-resolver>
</mvc:resolvers>
</mvc:resource-chain>
</mvc:resources>1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
您可以使用 ResourceUrlProvider 来重写 URL 并应用解析器和转换器的完整链条,例如,插入版本。MVC 配置提供了一个 ResourceUrlProvider Bean,以便它可以被注入到其他对象中。您还可以使用 ResourceUrlEncodingFilter 使重写对于 Thymeleaf、JSPs、FreeMarker 以及依赖于 HttpServletResponse#encodeURL 的 URL 标签的其他内容透明。
请注意,当同时使用 EncodedResourceResolver(例如,用于提供 gzip 或 brotli 编码的资源)和 VersionResourceResolver 时,您必须按此顺序注册它们。这确保基于未编码文件始终可靠地计算出基于内容的版本。
对于 WebJars,像 /webjars/jquery/1.2.0/jquery.min.js 这样的版本化 URL 是使用它们的推荐和最有效的方式。相关的资源位置已经在 Spring Boot 中预先配置好(或者可以通过 ResourceHandlerRegistry 手动配置),并且不需要添加 org.webjars:webjars-locator-core 依赖。
像 /webjars/jquery/jquery.min.js 这样的无版本 URL 通过 WebJarsResourceResolver 得到支持,当 org.webjars:webjars-locator-core 库存在于类路径上时,它会自动注册,但是以类路径扫描可能会减慢应用启动的速度为代价。解析器可以重写 URL 以包含 Jar 的版本,并且也可以匹配没有版本的传入 URL —— 例如,从 /webjars/jquery/jquery.min.js 到 /webjars/jquery/1.2.0/jquery.min.js。
Note:基于
ResourceHandlerRegistry的 Java 配置提供了更多的选项用于进行细粒度控制,例如,最后修改行为和优化资源解析。
1.11. 默认 Servlet
Spring MVC 允许将 DispatcherServlet 映射到 /(从而覆盖容器默认 Servlet 的映射),同时仍然允许由容器的默认 Servlet 处理静态资源请求。它配置了一个 DefaultServletHttpRequestHandler,其 URL 映射为 /**,并且相对于其他 URL 映射具有最低的优先级。
此处理器将所有请求转发到默认的 Servlet。因此,它必须在所有其他 URL HandlerMappings 的顺序中保持最后。如果你使用 <mvc:annotation-driven>,那就是这种情况。或者,如果你设置了自己的自定义 HandlerMapping 实例,一定要将其 order 属性设置为一个值,该值低于 DefaultServletHttpRequestHandler 的值,即 Integer.MAX_VALUE。
以下示例展示了如何使用默认设置启用此功能:
Java
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
以下示例展示了如何在 XML 中实现相同的配置:
XML
<mvc:default-servlet-handler/>覆盖 / Servlet 映射的注意事项是,必须通过名称而不是路径来检索默认 Servlet 的 RequestDispatcher。DefaultServletHttpRequestHandler 试图在启动时自动检测容器的默认 Servlet,使用大多数主要 Servlet 容器(包括 Tomcat、Jetty、GlassFish、JBoss、Resin、WebLogic 和 WebSphere)的已知名称列表。如果默认的 Servlet 已经被自定义配置了一个不同的名称,或者正在使用一个默认 Servlet 名称未知的不同 Servlet 容器,那么你必须明确提供默认 Servlet 的名称,如下例所示:
Java
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable("myCustomDefaultServlet");
}
}1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
以下示例展示了如何在 XML 中实现相同的配置:
XML
<mvc:default-servlet-handler default-servlet-name="myCustomDefaultServlet"/>1.12. 路径匹配
您可以自定义与路径匹配和 URL 处理相关的选项。有关各个选项的详细信息,请参阅 PathMatchConfigurer 的 JavaDoc。
以下示例展示了如何在 Java 配置中自定义路径匹配:
Java
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer
.setPatternParser(new PathPatternParser())
.addPathPrefix("/api", HandlerTypePredicate.forAnnotation(RestController.class));
}
private PathPatternParser patternParser() {
// ...
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
以下示例展示了如何在 XML 中实现相同的配置:
XML
<mvc:annotation-driven>
<mvc:path-matching
trailing-slash="false"
path-helper="pathHelper"
path-matcher="pathMatcher"/>
</mvc:annotation-driven>
<bean id="pathHelper" class="org.example.app.MyPathHelper"/>
<bean id="pathMatcher" class="org.example.app.MyPathMatcher"/>1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
1.13. 高级 Java 配置
@EnableWebMvc 导入了 DelegatingWebMvcConfiguration,它:
- 为 Spring MVC 应用程序提供默认的 Spring 配置;
- 检测并委托给
WebMvcConfigurer实现以自定义该配置;
对于高级模式,您可以移除 @EnableWebMvc,并直接从 DelegatingWebMvcConfiguration 扩展,而不是实现 WebMvcConfigurer,如下例所示:
Java
@Configuration
public class WebConfig extends DelegatingWebMvcConfiguration {
// ...
}1
2
3
4
2
3
4
您可以保留 WebConfig 中的现有方法,但现在您也可以覆盖基类中的 Bean 声明,并且您仍然可以在类路径上有任意数量的其他 WebMvcConfigurer 实现。
1.14. 高级 XML 配置
MVC 命名空间没有高级模式。如果您需要自定义无法更改的 Bean 的属性,您可以使用 Spring ApplicationContext 的 BeanPostProcessor 生命周期钩子,如下例所示:
Java
@Component
public class MyPostProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
// ...
}
}1
2
3
4
5
6
2
3
4
5
6
请注意,您需要将 MyPostProcessor 声明为一个 Bean,可以在 XML 中显式声明,或者通过 <component-scan/> 声明让其被检测到。
2. HTTP/2
Servlet 4 容器需要支持 HTTP/2,而 Spring Framework 5 与 Servlet API 4 兼容。从编程模型的角度来看,应用程序无需做任何特定的事情。然而,还需要考虑与服务器配置相关的事项。更多详细信息,请参阅 HTTP/2 Wiki 页面。
Servlet API 确实公开了一个与 HTTP/2 相关的构造。您可以使用 javax.servlet.http.PushBuilder 主动向客户端推送资源,它被支持作为 @RequestMapping 方法的方法参数。