Spring 4 官方文档学习(十一)Web MVC 框架之配置Spring MVC
内容列表:
- 启用MVC Java config 或 MVC XML namespace
- 修改已提供的配置
- 类型转换和格式化
- 校验
- 拦截器
- 内容协商
- View Controllers
- View Resolvers
- 服务于资源
- 回滚到默认的Servlet
- Path Matching - 路径匹配
- Message Converters - 消息转换器
- MVC Java config中的高级定制
- MVC namespace中的高级定制
在前面的文档中讲解了Spring MVC的特殊beans,以及DispatcherServlet使用的默认实现。在本部分,你会学习两种额外的方式来配置Spring MVC。分别是:MVC Java config 和 MVC XML namespace。
原文:
Section 22.2.1, “Special Bean Types In the WebApplicationContext” and Section 22.2.2, “Default DispatcherServlet Configuration” explained about Spring MVC’s special beans and the default implementations used by the
DispatcherServlet
.
MVC Java config 和 MVC namespace,提供了类似的默认配置,都覆盖了DispatcherServlet的默认配置。其目标是①让多数应用免于创建同样的配置,还是②提供更高级的构建来配置Spring MVC,不需要底层配置的相关知识。
你可以按照你的爱好来选择MVC Java config 或 MVC namespace。只是,在后面你会发现,使用MVC Java config,更容易发现底层的配置,从而可以对创建好的Spring MVC beans做出更细化的定制。
现在让我们开始吧。
1、启用MVC Java config 或 MVC XML namespace
想要启用MVC Java config,只需要将@EnableWebMvc添加到你的一个@Configuration class即可。
- @Configuration
- @EnableWebMvc
- public class WebConfig {
- }
或者在XML中,需要在你的DispatcherServlet context (或你的root context -- 如果没有定义DispatcherServlet context的话)内使用 <mvc:annotation-driven> 元素:
- <?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
- http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/mvc
- http://www.springframework.org/schema/mvc/spring-mvc.xsd">
- <mvc:annotation-driven/>
- </beans>
上面,已经注册了一个 RequestMappingHandlerMapping、一个RequestMappingHandlerAdapter、以及一个ExceptionHandlerExceptionResolver 以支持使用注解Controller的注解方法(如@RequestMapping、@ExceptionHandler)来处理request。
它还启用了如下内容:
- Spring 3 风格的类型转换 -- 通过一个ConversionService 实例 配合JavaBean PropertyEditors,用于Data Binding。
- 支持@NumberFormat注解通过ConversionService 来格式化Number字段。
- 支持使用@DateTimeFormat注解来格式化Date、Calendar、Long、以及Joda Time字段。
- 支持使用@Valid校验@Controller input -- 如果classpath中存在一个JSR-303 Provider。
- HttpMessageConverter支持@RequestMapping或@ExceptionHandler method的 @RequestBody method parameters和@ResponseBody method 返回值。 -- 比较长,其实就是支持handler (controller)的@RequestBody参数/@ResponseBody返回值。
下面是<mvc:annotation-driven> 设置的完整的HttpMessageConverter列表:
ByteArrayHttpMessageConverter
converts byte arrays.StringHttpMessageConverter
converts strings.ResourceHttpMessageConverter
converts to/fromorg.springframework.core.io.Resource
for all media types.SourceHttpMessageConverter
converts to/from ajavax.xml.transform.Source
.FormHttpMessageConverter
converts form data to/from aMultiValueMap<String, String>
.Jaxb2RootElementHttpMessageConverter
converts Java objects to/from XML — added if JAXB2 is present and Jackson 2 XML extension is not present on the classpath.MappingJackson2HttpMessageConverter
converts to/from JSON — added if Jackson 2 is present on the classpath.MappingJackson2XmlHttpMessageConverter
converts to/from XML — added if Jackson 2 XML extension is present on the classpath.AtomFeedHttpMessageConverter
converts Atom feeds — added if Rome is present on the classpath.RssChannelHttpMessageConverter
converts RSS feeds — added if Rome is present on the classpath.
See Section 22.16.12, “Message Converters” for more information about how to customize these default converters.
Jackson JSON 和 XML converters是使用Jackson2ObjectMapperBuilder创建的ObjectMapper实例们来创建的,其目的是提供一个更好的默认配置。
该builder定制了Jackson的默认properties:
DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
is disabled.MapperFeature.DEFAULT_VIEW_INCLUSION
is disabled.
它还自动注册了下列很有名的模块 -- 如果能够在classpath中检测到的话:
- jackson-datatype-jdk7: support for Java 7 types like
java.nio.file.Path
. - jackson-datatype-joda: support for Joda-Time types.
- jackson-datatype-jsr310: support for Java 8 Date & Time API types.
- jackson-datatype-jdk8: support for other Java 8 types like
Optional
.
2、修改已提供的配置
想要以Java形式定制默认的配置,你可以简单的实现WebMvcConfigurer接口,或者继承WebMvcConfigurerAdapter并重写需要的方法:
- @Configuration
- @EnableWebMvc
- public class WebConfig extends WebMvcConfigurerAdapter {
- // Override configuration methods...
- }
想要定制 <mvc:annotation-driven>的默认配置,需要检查其attributes和其子元素。可以查看Spring MVC XML schema,或者使用IDE的自动完成功能来探索可用的attributes和子元素。
3、类型转换和格式化
默认已注册了Number和Date类型的formatters,支持@NumberFormat和@DateTimeFormat注解。 还注册了对于Joda Time格式化库的完全支持 -- 需要在classpath中有Joda Time。想要注册自定义的formatters和converters,重写addFormatters方法即可:
- @Configuration
- @EnableWebMvc
- public class WebConfig extends WebMvcConfigurerAdapter {
- @Override
- public void addFormatters(FormatterRegistry registry) {
- // Add formatters and/or converters
- }
- }
在MVC namespace中,<mvc:annotation-driven>会应用同样的默认设置。如果想注册自己的formatters和converters,只需要提供一个ConversionService:
- <?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
- http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/mvc
- http://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>
See Section 9.6.4, “FormatterRegistrar SPI” and the
FormattingConversionServiceFactoryBean
for more information on when to use FormatterRegistrars.
4、校验
Spring提供了一个Validator接口,可被用于在应用的所有layers上的校验。在Spring MVC中,你可以将其配置成一个全局的Validator实例,用于所有@Valid或@Validated controller method argument的地方,和/或一个Controller内局部的Validator,通过一个@InitBinder方法。 全局的和局部的validator实例们可以组合校验。
Spring还支持 JSR-303/JSR-349 Bean Validation -- 通过LocalValidatorFactoryBean,LocalValidatorFactoryBean会将Spring的Validator接口适配到javax.validation.Validator。 该类可以被插入Spring MVC作为一个全局的validator,下面有讲。
使用@EnableWebMvc或 <mvc:annotation-driven>,会默认地在Spring MVC中自动注册Bean Validation支持 -- 通过LocalValidatorFactoryBean,前提是classpath中有一个Bean Validation Provider,如Hibernate Validator。
有时候,将LocalValidatorFactoryBean注入到controller或其他类中很方便。最简单的方法就是声明你自己的@Bean,并使用@Primary以避免与MVC Java config提供的那个发送冲突。
如果你更喜欢MVC Java config提供的那个,你会需要重写WebMvcConfigurationSupport的mvcValidator(),并声明方法显式地返回LocalValidatorFactory而非Validator。详见 Section 22.16.13, “Advanced Customizations with MVC Java Config”。
或者,你可以配置自己的全局 Validator实例:
- @Configuration
- @EnableWebMvc
- public class WebConfig extends WebMvcConfigurerAdapter {
- @Override
- public Validator getValidator(); {
- // return "global" validator
- }
- }
在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
- http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/mvc
- http://www.springframework.org/schema/mvc/spring-mvc.xsd">
- <mvc:annotation-driven validator="globalValidator"/>
- </beans>
想要联合全局的和局部的validation,只需要简单地添加一个或多个local validator(s):
- @Controller
- public class MyController {
- @InitBinder
- protected void initBinder(WebDataBinder binder) {
- binder.addValidators(new FooValidator());
- }
- }
使用这种最小化的配置,任何时间只要@Valid或@Validated method argument遇到了,就会被配置好的validators校验。任何校验都会自动的被暴露成BindingResult中的errors,可被方法参数访问,在Spring MVC HTML views中也是可渲染的。 -- 其实都是废话,就是说 method(..@Valid T t, BindingResult br)。
5、拦截器
HandlerInterceptor 或 WebRequestInterceptor,可被用于所有incoming requests 或 特定的URL path patterns。
Java形式注册拦截器:
- @Configuration
- @EnableWebMvc
- public class WebConfig extends WebMvcConfigurerAdapter {
- @Override
- public void addInterceptors(InterceptorRegistry registry) {
- registry.addInterceptor(new LocaleInterceptor());
- registry.addInterceptor(new ThemeInterceptor()).addPathPatterns("/**").excludePathPatterns("/admin/**");
- registry.addInterceptor(new SecurityInterceptor()).addPathPatterns("/secure/*");
- }
- }
在XML中使用 <MVC:Interceptors> 元素:
- <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:interceptor>
- <mvc:mapping path="/secure/*"/>
- <bean class="org.example.SecurityInterceptor"/>
- </mvc:interceptor>
- </mvc:interceptors>
6、内容协商
你可以配置Spring MVC如何判断request中的请求媒体类型。可用的选项是:①检查URL路径中的文件扩展名,②检查Accept header,③特定的query parameter,④或回滚到默认的内容类型 -- 当什么都不请求时。 默认,先检查request URI中的扩展名,再检查Accept header。
MVC Java config和 MVC namespace 默认会注册 json、xml、rss、atom,前提是classpath中有相应的依赖。可以显式地注册额外的path extension-to-media类型映射。
下面是通过MVC Java config定制内容协商选项的例子:
- @Configuration
- @EnableWebMvc
- public class WebConfig extends WebMvcConfigurerAdapter {
- @Override
- public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
- configurer.mediaType("json", MediaType.APPLICATION_JSON);
- }
- }
中MVC namespace中,<mvc:annotation-driven>元素有个 content-negotiation-manager attribute,它预期的是一个ContentNegotiationManager-- 可以使用ContentNegotiationManagerFactoryBean:
- <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>
如果不使用MVC Java config 或 MVC namespace,你会需要创建一个ContentNegotiationManager实例,并用它来配置RequestMappingHandlerMapping -- 用于request mapping目的,以及配置RequestMappingHandlerAdapter 和 ExceptionHandlerExceptionResolver -- 用于内容协商目的。
注意,ContentNegotiatingViewResolver 现在也可以使用一个ContentNegotiationManager来配置,所以你可以使用一个共享的实例。
更多的情况下,配置多个ContentNegotiationManager实例(可能包含定制的ContentNegotiationStrategy实现)可能很有用。例如,你可以使用一个ContentNegotiationManager来配置ExceptionHandlerExceptionResolver,然后总是将请求的媒体类型处理成”application/json”。或者,你可能想插入一个定制的策略,如果没有内容类型被请求时,使用一些逻辑来选择默认的内容类型--如XML或JSON。
7、View Controllers
有一种简便的方式来定义一个ParameterizableViewController --当调用时会立即转发到一个view。一般用于静态案例。
例如,以Java形式将对”/”的请求转发至”home” view:
- @Configuration
- @EnableWebMvc
- public class WebConfig extends WebMvcConfigurerAdapter {
- @Override
- public void addViewControllers(ViewControllerRegistry registry) {
- registry.addViewController("/").setViewName("home");
- }
- }
在XML中,可以使用<mvc:view-controller> 元素:
- <mvc:view-controller path="/" view-name="home"/>
8、View Resolvers
MVC config 简化了view resolvers的注册。
下面是一个Java config示例,配置了内容协商视图解决方案使用FreeMarker HTML 模板,还配置了Jackson作为默认JSON View:
- @Configuration
- @EnableWebMvc
- public class WebConfig extends WebMvcConfigurerAdapter {
- @Override
- public void configureViewResolvers(ViewResolverRegistry registry) {
- registry.enableContentNegotiation(new MappingJackson2JsonView());
- registry.jsp();
- }
- }
在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>
注意:FreeMarker、Velocity、Tiles、Groovy Markup和脚本模板,同样要求配置底层的view 技术。
MVC namespace提供了专用的元素。 例如,针对FreeMarker:
- <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>
在Java config中,只需要简单的添加相应的Configurer bean即可:
- @Configuration
- @EnableWebMvc
- public class WebConfig extends WebMvcConfigurerAdapter {
- @Override
- public void configureViewResolvers(ViewResolverRegistry registry) {
- registry.enableContentNegotiation(new MappingJackson2JsonView());
- registry.freeMarker().cache(false);
- }
- @Bean
- public FreeMarkerConfigurer freeMarkerConfigurer() {
- FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
- configurer.setTemplateLoaderPath("/WEB-INF/");
- return configurer;
- }
- }
9、服务于资源
该选项允许静态资源请求按照特定的URL pattern,由ResourceHttpRequestHandler来服务 -- 从Resource locations列表中的任意一个。这提供了一种便捷的方式来服务静态资源,不只是web app root的位置,还包括classpath (牛掰大了)。其cache-period property可以被用来设置失效headers (对于Page Speed and YSlow等工具来说,推荐设为1年),这样它们会被client更有效的使用。handler还会正确的evaluate Last-Modified header (如果有) -- 并在恰当的时候返回 304 status code,这样会避免不必要的重复资源获取。例如,想要使用 /resources/** 形式的URL pattern来请求 web root 下public-resources 文件夹中内容,你可以这样做:
- @Configuration
- @EnableWebMvc
- public class WebConfig extends WebMvcConfigurerAdapter {
- @Override
- public void addResourceHandlers(ResourceHandlerRegistry registry) {
- registry.addResourceHandler("/resources/**").addResourceLocations("/public-resources/");
- }
- }
或者在XML中:
- <mvc:resources mapping="/resources/**" location="/public-resources/"/>
设定 1年有效期:
- @Configuration
- @EnableWebMvc
- public class WebConfig extends WebMvcConfigurerAdapter {
- @Override
- public void addResourceHandlers(ResourceHandlerRegistry registry) {
- registry.addResourceHandler("/resources/**").addResourceLocations("/public-resources/").setCachePeriod(31556926);
- }
- }
XML中:
- <mvc:resources mapping="/resources/**" location="/public-resources/" cache-period="31556926"/>
更多详见 Spring 4 官方文档学习(十一)Web MVC 框架之HTTP caching support 。
注意:mapping attribute 必须是一个Ant 模式的,这样才能被SimpleUrlHandlerMapping使用;location attribute 必须指定一个或多个有效的资源目录。 多个资源位置可以使用逗号间隔。指定的位置会按照指定的顺序被检查。例如,想要同时支持 web root 和classpath中任何jar中的 /META-INF/public-web-resources/ 路径,可以这样:
- @EnableWebMvc
- @Configuration
- public class WebConfig extends WebMvcConfigurerAdapter {
- @Override
- public void addResourceHandlers(ResourceHandlerRegistry registry) {
- registry.addResourceHandler("/resources/**")
- .addResourceLocations("/", "classpath:/META-INF/public-web-resources/");
- }
- }
在XML中:
- <mvc:resources mapping="/resources/**" location="/, classpath:/META-INF/public-web-resources/"/>
当资源可能随着新版本的部署而发生改变时,建议在请求资源的mapping pattern中加入一个版本字符串,这样你可以强制客户端请求新部署版本的资源。 框架天然支持带版本的URLs,且可以通过配置resource handler的resource chain来启用。该chain由一个或多个ResourceResolver实例(伴有一个或多个ResourceTransformer实例)组成。它们一起可以为资源提供任意的resolution和transformation。
内置的VersionResourceResolver,可以被配置不同的策略。例如,一个FixedVersionStrategy可以使用一个property、一个date,或其他作为版本。一个ContentVersionStrategy 使用根据资源内容计算的MD5 hash(也被叫做fingerprinting URLs)作为版本。 注意,VersionResourceResolver会自动使用resolved version strings作为 HTTP ETag header的值。
ContentVersionStrategy是一个很好的默认选择,除非不能使用 (例如,当使用JavaScript 模块加载器时)。 你可以配置不同的版本策略。务必记住,基于内容计算的版本是很耗费系统资源的,因此,在生产模型中应该启用resource chain 缓存。
Java config 例子:
- @Configuration
- @EnableWebMvc
- public class WebConfig extends WebMvcConfigurerAdapter {
- @Override
- public void addResourceHandlers(ResourceHandlerRegistry registry) {
- registry.addResourceHandler("/resources/**")
- .addResourceLocations("/public-resources/")
- .resourceChain(true).addResolver(
- new VersionResourceResolver().addContentVersionStrategy("/**"));
- }
- }
XML例子:
- <mvc:resources mapping="/resources/**" location="/public-resources/">
- <mvc:resource-chain>
- <mvc:resource-cache/>
- <mvc:resolvers>
- <mvc:version-resolver>
- <mvc:content-version-strategy patterns="/**"/>
- </mvc:version-resolver>
- </mvc:resolvers>
- </mvc:resource-chain>
- </mvc:resources>
为了让上面的内容正常工作,应用必须在URLs中带有版本。 最简单的方式就是配置一个ResourceUrlEncodingFilter,它封装了response,并重写了其encodeURL method。在JSPs、FreeMarker、Velocity、和任何调用response encodeURL method的其他view技术中,都可以工作。或者,一个应用也可以注入和直接使用 ResourceUrlProvider bean,MVC Java config 和 MVC namespace会自动声明它。
Webjars are also supported with WebJarsResourceResolver
, which is automatically registered when the "org.webjars:webjars-locator"
library is on classpath. This resolver allows the resource chain to resolve version agnostic libraries from HTTP GET requests "GET /jquery/jquery.min.js"
will return resource "/jquery/1.2.0/jquery.min.js"
. It also works by rewriting resource URLs in templates <script src="/jquery/jquery.min.js"/> → <script src="/jquery/1.2.0/jquery.min.js"/>
.
10、回滚到默认的Servlet
这允许将 DispatcherServlet 映射到 “/”(因此,覆盖了容器的default Servlet的映射),同时,仍然允许容器的default Servlet来处理静态资源请求。它配置了一个DefaultServletHttpRequestHandler,并映射到 “/**”,该映射具有最低的优先级。
该Handler 会将所有请求转发给default Servlet。因此,它在所有其他URL HandlerMappings中排名最后很重要(就是必须放在最后的意思)。当你使用<mvc:annotation-driven> 或 当你在设置你自己定制的HandlerMapping实例时,其order property的值应比DefaultServletHttpRequestHandler的值小,嗯嗯,后者是 Integer.MAX_VALUE
。
To enable the feature using the default setup use:
- @Configuration
- @EnableWebMvc
- public class WebConfig extends WebMvcConfigurerAdapter {
- @Override
- public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
- configurer.enable();
- }
- }
或者,在XML中:
- <mvc:default-servlet-handler/>
针对覆盖 “/” Servlet mapping的警告是:default Servlet 的 RequestDispatcher 必须通过name来获取,而非通过path。DefaultServletHttpRequestHandler 会在Servlet容器启动时试图自动探测其default Servlet -- 使用一个包含大多数已知Servlet容器的name列表(包括Tomcat、Jetty、GlassFish、JBoss、Resin、WebLogic、WebSphere) 。 如果default Servlet已经被配置了不同的name,或者如果使用了一个不同的Servlet容器(不知其default Servlet name),那么必须按照如下方式来提供default Servlet name:
- @Configuration
- @EnableWebMvc
- public class WebConfig extends WebMvcConfigurerAdapter {
- @Override
- public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
- configurer.enable("myCustomDefaultServlet");
- }
- }
或者在XML中:
- <mvc:default-servlet-handler default-servlet-name="myCustomDefaultServlet"/>
11、Path Matching - 路径匹配
这里允许针对URL mapping和path matching 自定义不同的设置。 针对每个选项的详细信息,请检查PathMatchConfigurer API。
下面是一个Java config例子:
- @Configuration
- @EnableWebMvc
- public class WebConfig extends WebMvcConfigurerAdapter {
- @Override
- public void configurePathMatch(PathMatchConfigurer configurer) {
- configurer
- .setUseSuffixPatternMatch(true)
- .setUseTrailingSlashMatch(false)
- .setUseRegisteredSuffixPatternMatch(true)
- .setPathMatcher(antPathMatcher())
- .setUrlPathHelper(urlPathHelper());
- }
- @Bean
- public UrlPathHelper urlPathHelper() {
- //...
- }
- @Bean
- public PathMatcher antPathMatcher() {
- //...
- }
- }
或在XML中使用<mvc:path-matching> 元素:
- <mvc:annotation-driven>
- <mvc:path-matching
- suffix-pattern="true"
- trailing-slash="false"
- registered-suffixes-only="true"
- 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"/>
12、Message Converters - 消息转换器
针对HttpMessageConverter的定制,可以通过重写configureMessageConverters() 或重写extendMessageConverters()来实现,二者不同之处在于:前者会取代Spring MVC创建的默认转换器,后者则是添加额外的转换器。(个人推荐后者)
下面是一个取代默认设置的例子:
- @Configuration
- @EnableWebMvc
- public class WebConfiguration extends WebMvcConfigurerAdapter {
- @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.xml().build()));
- }
- }
在该例子中,使用 Jackson2ObjectMapperBuilder
来为MappingJackson2HttpMessageConverter
和MappingJackson2XmlHttpMessageConverter
创建一个通用的配置,该配置:支持缩进、自定义的日期格式‘jackson-module-parameter-names的注册(会添加访问parameter names的支持 -- Java 8中的功能)。
启用Jackson XML的缩进支持,需要jaskson-dataformat-xml 还有 woodstox-core-asl 依赖。
其他有趣的可用Jackson模块包括:
- jackson-datatype-money: support for
javax.money
types (unofficial module) - jackson-datatype-hibernate: support for Hibernate specific types and properties (including lazy-loading aspects)
在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"/>
13、MVC Java config中的高级定制
如果你在前面的例子中看到的一样,MVC Java config 和 MVC namespace 都提供了高级别的指令 -- 不需要高深的底层知识。相反,它会帮助你将精力放在应用上面。然而,某些时候你的确可能需要更细化的控制,或者你只是简单地想理解底层的配置。
迈向更细化的控制的第一步,就是查看底层的beans。在MVC Java config 中你可以看到javadocs 和 WebMvcConfigurationSupport中的@Bean methods。 通过@EnableWebMvc注解,可以自动导入该类中的配置。 事实上,你点开@EnableWebMvc 就可以看到 @Import语句。
第二步就是自定义下WebMvcConfigurationSupport创建的某个bean的一个property,或者,干脆提供你自己的实例。这需要两件事情:移除@EnableWebMvc注解,以阻止导入,然后继承DelegatingWebMvcConfiguration -- 它是WebMvcConfigurationSupport的一个子类。 见下面的例子:
- @Configuration
- public class WebConfig extends DelegatingWebMvcConfiguration {
- @Override
- public void addInterceptors(InterceptorRegistry registry){
- // ...
- }
- @Override
- @Bean
- public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
- // Create or let "super" create the adapter
- // Then customize one of its properties
- }
- }
一个应用应该只有一个继承自DelegatingWebMVCConfiguration的配置 或 单一的@EnableWebMvc class, 因为它们会注册相同的底层beans。
以这种方式修改beans,不会阻止你使用任何更高级别的方式 -- 就是前面讲述的那些方式。WebMvcConfigurerAdapter的子类们和WebMvcConfigurer实现们 仍然被使用。
14、MVC namespace中的高级定制
好吧,MVC namespace中更细化的控制有点麻烦。
建议配置一个 BeanPostProcessor,用它来侦探你想定制的bean,然后修改器properties即可。例如:
- @Component
- public class MyPostProcessor implements BeanPostProcessor {
- public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
- if (bean instanceof RequestMappingHandlerAdapter) {
- // Modify properties of the adapter
- }
- }
- }
这里要注意,MyPostProcessor 需要被包含在一个 <component scan/>中,这样能够自动被侦测到。或者,如果你喜欢,也可以将其显式地声明为一个XML bean定义。
官方文档链接:
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-config
Spring 4 官方文档学习(十一)Web MVC 框架之配置Spring MVC的更多相关文章
- Spring 4 官方文档学习(十一)Web MVC 框架之resolving views 解析视图
接前面的Spring 4 官方文档学习(十一)Web MVC 框架,那篇太长,故另起一篇. 针对web应用的所有的MVC框架,都会提供一种呈现views的方式.Spring提供了view resolv ...
- Spring 4 官方文档学习(十一)Web MVC 框架
介绍Spring Web MVC 框架 Spring Web MVC的特性 其他MVC实现的可插拔性 DispatcherServlet 在WebApplicationContext中的特殊的bean ...
- Spring 4 官方文档学习(十二)View技术
关键词:view technology.template.template engine.markup.内容较多,按需查用即可. 介绍 Thymeleaf Groovy Markup Template ...
- Spring Boot 官方文档学习(一)入门及使用
个人说明:本文内容都是从为知笔记上复制过来的,样式难免走样,以后再修改吧.另外,本文可以看作官方文档的选择性的翻译(大部分),以及个人使用经验及问题. 其他说明:如果对Spring Boot没有概念, ...
- Spring boot官方文档学习(一)
个人说明:本文内容都是从为知笔记上复制过来的,样式难免走样,以后再修改吧.另外,本文可以看作官方文档的选择性的翻译(大部分),以及个人使用经验及问题. 其他说明:如果对Spring Boot没有概念, ...
- Spring Framework 官方文档学习(四)之Validation、Data Binding、Type Conversion(二)
接前一篇 Spring Framework 官方文档学习(四)之Validation.Data Binding.Type Conversion(一) 本篇主要内容:Spring Type Conver ...
- Spring Framework 官方文档学习(四)之Validation、Data Binding、Type Conversion
本篇太乱,请移步: Spring Framework 官方文档学习(四)之Validation.Data Binding.Type Conversion(一) 写了删删了写,反复几次,对自己的描述很不 ...
- Spring Framework 官方文档学习(四)之Validation、Data Binding、Type Conversion(一)
题外话:本篇是对之前那篇的重排版.并拆分成两篇,免得没了看的兴趣. 前言 在Spring Framework官方文档中,这三者是放到一起讲的,但没有解释为什么放到一起.大概是默认了读者都是有相关经验的 ...
- 20191127 Spring Boot官方文档学习(9.1-9.3)
9."使用方法"指南 9.1.Spring Boot应用程序 9.1.1.创建自己的FailureAnalyzer FailureAnalyzer被包装在FailureAnalys ...
随机推荐
- mysql 外键约束
外键的定义语法:[CONSTRAINT symbol] FOREIGN KEY [id] (index_col_name, ...) REFERENCES tbl_name (index_col ...
- windows下用一台机器配置分布式redis(主从服务器)
目录1.Replication的工作原理2.如何配置Redis主从复制 1.Replication的工作原理在Slave启动并连接到Master之后,它将主动发送一条SYNC命令.此后Master将启 ...
- JVM参数(二)参数分类和即时(JIT)编译器诊断
在这个系列的第二部分,我来介绍一下HotSpot JVM提供的不同类别的参数.我同样会讨论一些关于JIT编译器诊断的有趣参数. JVM 参数分类 HotSpot JVM 提供了三类参数.第一类包括了标 ...
- Linux 11g rac PSU
PSU补丁:p22191577_112040_Linux-x86-64.zipOPATCH工具:p6880880_112000_LINUX.zip 解压OPATCH工具 覆盖到/u01/11.2.0/ ...
- mysql存储emoji表情
微信获取的用户昵称nickname中带有emoji表情,转换成字符码后是这种形式“\xF0\x9F\x91\x8D\xE6\x94...”, 直接保存可能出现以下错误 Caused by: java. ...
- alarm rtc
http://sharp2wing.iteye.com/blog/1329518 http://blog.csdn.net/sking002007/article/details/6593809 io ...
- 新书发布《大数据时代的IT架构设计》
<大数据时代的IT架构设计>以大数据时代为背景,邀请著名企业中的一线架构师,结合工作中的实际案例展开与架构相关的讨论.<大数据时代的IT架构设计>作者来自互联网.教育.传统行业 ...
- brew安装
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; color: #454545 } span.s1 { font: 12. ...
- 码农谷 找出N之内的所有完数
题目描述 一个数如果恰好等于它的因子之和,这个数就称为"完数". 例如,6的因子为1.2.3,而6=1+2+3,因此6是"完数". 编程序找出N之内的所有完数, ...
- IOS App Integrate Google Map Problems and Method to solve them
1. You must get a key in google developer center, and register it in below function in AppDelegate.m ...