springboot情操陶冶-web配置(二) (2)

由上述代码得知,将servlet注入至tomcat容器是通过ServletContextInitializer接口的实现类ServletRegistrationBean来实现的,具体的本文不展开,不过如果用户想把Servlet或者Filter注入至tomcat,则常用此Bean来操作即可

WebMvcAutoConfiguration

DispatcherServlet组件创建并注入至web容器后,接下来便是对mvc的相关配置,笔者也按几个步骤来分析

No.1 脑壳注解看一下

@Configuration @ConditionalOnWebApplication(type = Type.SERVLET) @ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class }) @ConditionalOnMissingBean(WebMvcConfigurationSupport.class) @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10) @AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, ValidationAutoConfiguration.class }) public class WebMvcAutoConfiguration { }

此配置也是根据上文中的DispatcherServletAutoConfiguration注入至bean工厂后再生效。

No.2 Filter集合

1.HiddenHttpMethodFilter-隐性传播PUT/DELETE/PATCH请求

@Bean @ConditionalOnMissingBean(HiddenHttpMethodFilter.class) public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() { // 默认对post请求的包读取_method参数指定的方法,然后再作转换 return new OrderedHiddenHttpMethodFilter(); }

隐性的通过methodParam参数来传播PUT/DELETE/PATCH请求,默认参数名为*_method*,也可用户自行配置

2.HttpPutFormContentFilter-显性响应PUT/DELETE/PATCH请求

// spring.mvc.formcontent.putfilter.enabled不指定或者值不为false则生效 @Bean @ConditionalOnMissingBean(HttpPutFormContentFilter.class) @ConditionalOnProperty(prefix = "spring.mvc.formcontent.putfilter", name = "enabled", matchIfMissing = true) public OrderedHttpPutFormContentFilter httpPutFormContentFilter() { // 直接对PUT/DELETE/PATCH请求进行响应,其order值大于OrderedHiddenHttpMethodFilter return new OrderedHttpPutFormContentFilter(); }

其一般与上述的OrderedHiddenHttpMethodFilter搭配使用,其order值大于前者所以排在后面响应PUT等请求

No.3 EnableWebMvcConfiguration内部类,其类同@EnableWebMvc注解,类同我们常用spring配置的mvc:annotation-driven。由于代码过多,就挑选几个来看

@Configuration public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration { // 注册RequestMappingHandlerAdapter组件 @Bean @Override public RequestMappingHandlerAdapter requestMappingHandlerAdapter() { RequestMappingHandlerAdapter adapter = super.requestMappingHandlerAdapter(); adapter.setIgnoreDefaultModelOnRedirect(this.mvcProperties == null || this.mvcProperties.isIgnoreDefaultModelOnRedirect()); return adapter; } // 注册RequestMappingHanlderMapping组件 @Bean @Primary @Override public RequestMappingHandlerMapping requestMappingHandlerMapping() { // Must be @Primary for MvcUriComponentsBuilder to work return super.requestMappingHandlerMapping(); } // 校验器组件 @Bean @Override public Validator mvcValidator() { if (!ClassUtils.isPresent("javax.validation.Validator", getClass().getClassLoader())) { return super.mvcValidator(); } return ValidatorAdapter.get(getApplicationContext(), getValidator()); } // 异常处理组件 @Override protected ExceptionHandlerExceptionResolver createExceptionHandlerExceptionResolver() { if (this.mvcRegistrations != null && this.mvcRegistrations .getExceptionHandlerExceptionResolver() != null) { return this.mvcRegistrations.getExceptionHandlerExceptionResolver(); } return super.createExceptionHandlerExceptionResolver(); } }

主要是用来注册响应前端请求的插件集合,具体的怎么整合可见笔者置顶的spring文章,里面有提,就不在此处展开了
温馨提示:笔者此处提醒下此类是DelegatingWebMvcConfiguration的实现类,其本身也被注解@Configuration修饰,其内部的setConfigurers()方法有助于集结所有实现了WebMvcConfigurer接口的集合,所以用户可通过实现此接口来扩展mvc的相关配置

private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite(); @Autowired(required = false) public void setConfigurers(List<WebMvcConfigurer> configurers) { if (!CollectionUtils.isEmpty(configurers)) { this.configurers.addWebMvcConfigurers(configurers); } }

No.4 WebMvcAutoConfigurationAdapter内部类(WebMvcConfigurer接口实现类)-在上述的MVC组件的基础上新增其他的组件,包含视图组件、消息处理器组件等。
限于代码过长,笔者此处也挑选几个来看

// 消息处理器集合配置 @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { converters.addAll(this.messageConverters.getConverters()); } // 对路径请求的配置 @Override public void configurePathMatch(PathMatchConfigurer configurer) { // 对应spring.mvc.pathmatch.use-suffix-pattern,默认为false configurer.setUseSuffixPatternMatch( this.mvcProperties.getPathmatch().isUseSuffixPattern()); // 对应spring.mvc.patchmatch.use-registered-suffix-pattern,默认为false configurer.setUseRegisteredSuffixPatternMatch( this.mvcProperties.getPathmatch().isUseRegisteredSuffixPattern()); } // 创建jsp视图解析器 @Bean @ConditionalOnMissingBean public InternalResourceViewResolver defaultViewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); // 对应spring.mvc.view.prefix,默认为空 resolver.setPrefix(this.mvcProperties.getView().getPrefix()); // 对应spring.mvc.view.suffix,默认为空 resolver.setSuffix(this.mvcProperties.getView().getSuffix()); return resolver; } // 静态文件访问配置 @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { // 对应spring.resource.add-mappings,默认为true if (!this.resourceProperties.isAddMappings()) { logger.debug("Default resource handling disabled"); return; } Duration cachePeriod = this.resourceProperties.getCache().getPeriod(); CacheControl cacheControl = this.resourceProperties.getCache() .getCachecontrol().toHttpCacheControl(); if (!registry.hasMappingForPattern("/webjars/**")) { customizeResourceHandlerRegistration(registry .addResourceHandler("/webjars/**") .addResourceLocations("classpath:/META-INF/resources/webjars/") .setCachePeriod(getSeconds(cachePeriod)) .setCacheControl(cacheControl)); } // 对应spring.mvc.static-path-pattern,默认为/** String staticPathPattern = this.mvcProperties.getStaticPathPattern(); if (!registry.hasMappingForPattern(staticPathPattern)) { customizeResourceHandlerRegistration( registry.addResourceHandler(staticPathPattern) // 对应spring.resources.static-locations .addResourceLocations(getResourceLocations( this.resourceProperties.getStaticLocations())) .setCachePeriod(getSeconds(cachePeriod)) .setCacheControl(cacheControl)); } } // 欢迎界面配置,一般可在static或者项目根目录下配置index.html界面即可 @Bean public WelcomePageHandlerMapping welcomePageHandlerMapping( ApplicationContext applicationContext) { return new WelcomePageHandlerMapping( new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(), this.mvcProperties.getStaticPathPattern()); } 小结

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wppzdz.html