通过后面的介绍,咱们晓得Spring MVC是一个以DispatcherServlet为核心,泛滥组件协同工作的Servlet服务。Spring中容许用户灵便的配置MVC中的各个组件,这就是Spring MVC配置的意义。本文会对Spring提供的各个MVC配置进行具体的介绍,本文次要参考了Spring的官网文档。

MVC配置

启用MVC配置

应用MVC配置的第一步必定是开启MVC配置,Spring提供了@EnableWebMvc注解来启用MVC配置,该注解会引入解析MVC配置的组件。

@Configuration@EnableWebMvcpublic class WebConfig {}

WebMvcConfigurer

MVC的组件比拟多,构造比较复杂,用户在不理解源码的状况下很难间接进行配置,所以Spring提供了WebMvcConfigurer用于通知用户有哪些属性能够配置。下文咱们会一一介绍接口中的办法。

类型转换服务

咱们能够通过FormatterRegistry向配置中注册类型转换和格式化等服务,如下就配置了MVC日期与String类型之间的转换逻辑。

@Configuration@EnableWebMvcpublic class WebConfig implements WebMvcConfigurer {    @Override    public void addFormatters(FormatterRegistry registry) {        DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();        registrar.setUseIsoFormat(true);        registrar.registerFormatters(registry);    }}

校验服务

Spring容器默认提供了参数校验服务Validator,Controller中的参数会由Validator进行校验,MVC配置容许用户自定义校验逻辑,接口定义如下所示:

@Configuration@EnableWebMvcpublic class WebConfig implements WebMvcConfigurer {    @Override    public Validator getValidator() {        // ...    }}

拦截器

Spring容许用户对所有的申请进行对立解决,如权限校验、时区参数设置等等,解决逻辑能够放在申请解决前、申请解决后和申请解决实现,配置的逻辑如下所示。

@Configuration@EnableWebMvcpublic class WebConfig implements WebMvcConfigurer {    @Override    public void addInterceptors(InterceptorRegistry registry) {        registry.addInterceptor(new LocaleChangeInterceptor());        registry.addInterceptor(new ThemeChangeInterceptor()).addPathPatterns("/**").excludePathPatterns("/admin/**");        registry.addInterceptor(new SecurityInterceptor()).addPathPatterns("/secure/*");    }}

音讯转换服务

下面咱们介绍了FormatterRegistry,FormatterRegistry次要提供了简略类型之间的转换,如String转int等,然而对于简单申请体的转换,如@RequestBody中的JSON反序列化为对象等操作,就须要HttpMessageConverter的参加了。Spring默认提供了很多常见的转换服务如Jackson转换和货币日期等的转换。

@Configuration@EnableWebMvcpublic 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()));    }}

View配置

Spring运行依据申请门路间接返回View视图,用户能够通过配置ViewControllerRegistry实现这个性能。

@Configuration@EnableWebMvcpublic class WebConfig implements WebMvcConfigurer {    @Override    public void addViewControllers(ViewControllerRegistry registry) {        registry.addViewController("/").setViewName("home");    }}

Spring还容许用户自定以视图解析逻辑并通过ViewResolverRegistry注册到MVC中:

@Configuration@EnableWebMvcpublic 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;    }}

动态资源配置

如果用户某次申请的数据是动态资源,那么这次申请不应该由Controller逻辑进行解决。Spring提供了ResourceHandlerRegistry让用户配置动态资源匹配规定。

@Configuration@EnableWebMvcpublic class WebConfig implements WebMvcConfigurer {    @Override    public void addResourceHandlers(ResourceHandlerRegistry registry) {        registry.addResourceHandler("/resources/**")            .addResourceLocations("/public", "classpath:/static/")            .setCacheControl(CacheControl.maxAge(Duration.ofDays(365)));    }}

当DispatcherServlet映射到"/"门路后,咱们依然能够配置解决动态资源的默认Servlet,动态资源的映射门路是"/**",优先级比"/"低。个别状况下动态资源的Servlet应该是最低的,启用动态资源的servelt的示例如下所示:

@Configuration@EnableWebMvcpublic class WebConfig implements WebMvcConfigurer {    @Override    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {        configurer.enable();    }}
@Configuration@EnableWebMvcpublic class WebConfig implements WebMvcConfigurer {    @Override    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {        configurer.enable("myCustomDefaultServlet");    }}

门路匹配规定

咱们都晓得在Controller上增加@RequestMapping办法之后,Spring会把申请映射到对应的Controller办法上,那么咱们可不可以管制这个门路匹配过程呢?Spring提供了PathMatchConfigurer让用户能够配置门路匹配规定:

@Configuration@EnableWebMvcpublic class WebConfig implements WebMvcConfigurer {    @Override    public void configurePathMatch(PathMatchConfigurer configurer) {        configurer            .setPatternParser(new PathPatternParser())            .addPathPrefix("/api", HandlerTypePredicate.forAnnotation(RestController.class));    }    private PathPatternParser patternParser() {        // ...    }}

高级配置

@EnableWebMvc注解的原理就是向容器中注入类名为DelegatingWebMvcConfiguration,该类会读取各个WebMvcConfigurer并对MVC进行配置。所以咱们也能够不应用@EnableWebMvc,通过自定义DelegatingWebMvcConfiguration的模式对MVC进行更灵便的配置。

@Configurationpublic class WebConfig extends DelegatingWebMvcConfiguration {    // ...}

我是御狐神,欢送大家关注我的微信公众号:wzm2zsd

本文最先公布至微信公众号,版权所有,禁止转载!