通过前面的介绍,我们知道SpringMVC是一个以DispatcherServlet为核心的Servlet服务,众多组件协同工作。Spring允许用户在MVC中灵活配置各种组件,这就是SpringMVC配置的意义。本文将详细介绍Spring提供的各种MVC配置。本文主要参考了Spring的官方文档。MVC配置启用MVC配置使用MVC配置的第一步是启用MVC配置。Spring提供@EnableWebMvc注解开启MVC配置,会引入解析MVC配置的组件。@Configuration@EnableWebMvcpublicclassWebConfig{}WebMvcConfigurerMVC组件多,结构复杂。用户在不知道源码的情况下很难直接配置,所以Spring提供了WebMvcConfigurer来告诉用户哪些属性可以配置。下面我们将接口中的方法一一介绍。类型转换服务我们可以通过FormatterRegistry向配置注册类型转换和格式化服务。MVC日期和String类型的转换逻辑配置如下。@Configuration@EnableWebMvc公共类WebConfig实现WebMvcConfigurer{@OverridepublicvoidaddFormatters(FormatterRegistryregistry){DateTimeFormatterRegistrarregistrar=newDateTimeFormatterRegistrar();registrar.setUseIsoFormat(true);启用参数校验服务Validator后,Controller中的参数会被Validator校验。MVC配置允许用户自定义验证逻辑。接口定义如下:@Configuration@EnableWebMvcpublicclassWebConfigimplementsWebMvcConfigurer{@OverridepublicValidatorgetValidator(){//...}}拦截器Spring允许用户统一处理所有的请求,比如权限验证,时间zone参数设置等。处理逻辑可以放在请求处理之前,请求处理之后,请求处理完成之后。配置逻辑如下。@Configuration@EnableWebMvcpublicclassWebConfigimplementsWebMvcConfigurer{@OverridepublicvoidaddInterceptors(InterceptorRegistryregistry){registry.addInterceptor(newLocaleChangeInterceptor());}registry.addInterceptor(newThemeChangeInterceptor()).addPathPatterns("/**"/admin/**");registry.addInterceptor(newSecurityInterceptor()).addPathPatterns("/secure/*");}}消息转换服务上面我们介绍了FormatterRegistry,FormatterRegistry主要提供简单类型之间的转换,比如String到int等,但是对于复杂请求体的转换,比如@RequestBody中的JSON反序列化为对象等,HttpMessageConverter的参与是必须的,Spring默认提供了很多常用的转换服务,比如Jackson转换,货币日期转换。@Configuration@EnableWebMvc公共类WebConfiguration实现WebMvcConfigurer{@OverridepublicvoidconfigureMessageConverters(List>converters){Jackson2ObjectMapperBuilderbuilder=newJackson2ObjectMapperBuilder().indentOutput(true).dateFormaty("SimpleDyddy")).modulesToInstall(newParameterNamesModule());converters.add(newMappingJackson2HttpMessageConverter(builder.build()));converters.add(newMappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true).build()));}}View配置Spring操作直接根据请求路径返回View视图,用户可以通过配置ViewControllerRegistry实现该功能。@Configuration@EnableWebMvcpublicclassWebConfigimplementsWebMvcConfigurer{@OverridepublicvoidaddViewControllers(ViewControllerRegistryregistry){registry.addViewController("/").setViewName("home");}}Spring也允许用户自定义视图解析逻辑,通过ViewResolverRegistry在MVC中注册:registry.freeMarker().cache(FreeMarkerConfalse)freeMarkerConfigurer(){FreeMarkerConfigurer配置器=newFreeMarkerConfigurer();configurer.setTemplateLoaderPath("/freemarker");返回配置器;}}静态资源配置如果用户请求的数据是静态资源,那么这个请求就不应该由Controller逻辑去处理。Spring提供ResourceHandlerRegistry允许用户配置静态资源匹配规则。@Configuration@EnableWebMvc公共类WebConfig实现WebMvcConfigurer{@OverridepublicvoidaddResourceHandlers(ResourceHandlerRegistryregistry){registry.addResourceHandler("/resources/**").addResourceLocations("/public","classpath:/static/").setCacheControl(CacheControl.maxAge(Duration.ofDays(365)));}}当DispatcherServlet映射到“/”路径后,我们仍然可以配置默认的处理静态资源的Servlet。静态资源的映射路径为“/**”,优先级低于“/”。一般来说,静态资源的Servlet应该是最低级的。为静态资源启用servlet的示例如下:}}@Configuration@EnableWebMvcpublicclassWebConfigimplementsWebMvcConfigurer{@OverridepublicvoidconfigureDefaultServletHandling(DefaultServletHandlerConfigurerconfigurer){configurer.enable("myCustomDefaultServlet");到对应的Controller方法,是否可以控制路径匹配过程呢?Spring提供PathMatchConfigurer允许用户配置路径匹配规则:@Configuration@EnableWebMvcpublicclassWebConfigimplementsWebMvcConfigurer{@OverridepublicvoidconfigurePathMatch(PathMatchConfigurerconfigurer){configurer.setPatternParser(newPathPatternParser()).addPathPrefixand("/TypeHapi"forAnnotation(RestController.class));}privatePathPatternParserpatternParser(){//...}}高级配置的原理@EnableWebMvc注解是在容器中注入类名DelegatingWebMvcConfiguration,它会读取每一个WebMvcConfigurer并进行MVCConfiguration这样我们也可以更灵活的配置MVC通过自定义DelegatingWebMvcConfiguration而不使用@EnableWebMvc。@ConfigurationpublicclassWebConfigextendsDelegatingWebMvcConfiguration{//...}我是玉狐大神,欢迎大家关注我的微信公众号:wzm2zsd