在spring-boot-2.2.5中对MVC自动配置类进行的更改,之前的WebMvcConfigurerAdapter类声明为过时的,现在进行自定义扩展需要实现WebMvcConfigurer类重写其中的方法进行扩展
If you want to keep those Spring Boot MVC customizations and make more MVC customizations (interceptors, formatters, view controllers, and other features), you can add your own @Configuration class of type WebMvcConfigurer but without @EnableWebMvc.
如果要保留这些Spring Boot MVC定制并进行更多的MVC定制(拦截器,格式化程序,视图控制器和其他功能),则可以添加自己的类型为WebMvcConfigurer的@Configuration类,但不添加 @EnableWebMvc。
注意:
1、扩展功能是添加配置类去实现 WebMvcconfigurer 类,springboot的自动默认配置同事生效
2、如果实现的是:WebMvcConfigurationSupport类,则springboot默认的自动配置类不生效
在总动配置类上有@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)注解
原理:
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/success").setViewName("success");
}
}
1) addInterceptor:需要一个实现HandlerInterceptor接口的拦截器实例或者WebRequestInterceptor接口的实例
2)在实现了webMvcConfigur类的自定义配置类中重写addInterceptor方法,将自定义的拦截器进行注册
addPathPatterns:用于设置拦截器的过滤路径规则;
addPathPatterns("/**")对所有请求都拦截
excludePathPatterns:用于设置不需要拦截的过滤规则
拦截器主要用途:进行用户登录状态的拦截,日志的拦截等。
先创建自定义的拦截器类MyIntercepter
自定义的interceptinterceptor可以实现HandlerInterceptor或者WebRequestInterceptor
然后将自定义的拦截器进行注册
public class MyMvcInterceptor implements HandlerInterceptor {
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion");
}
/**
* 这里是有一个返回值的,如果返回值为true,继续执行,如果返回值为false则不执行后续的操作
* 这个方法在WebRequestInterceptor中则无返回值
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//ServletRequestUtils.getStringParameter(request,"ss");
System.out.println("preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle");
}
}
public class MyMvcRequestInterceptor implements WebRequestInterceptor {
@Override
public void preHandle(WebRequest request) throws Exception {
System.out.println("r----------preHandle");
}
@Override
public void postHandle(WebRequest request, ModelMap model) throws Exception {
System.out.println("r----------postHandle");
}
@Override
public void afterCompletion(WebRequest request, Exception ex) throws Exception {
System.out.println("r----------afterCompletion");
}
}
在配置类中配置自定义拦截器及规则,使拦截器生效
@Override
public void addInterceptors(InterceptorRegistry registry) {
InterceptorRegistration interceptorRegistration = registry.addInterceptor(new MyInterceper()).addPathPatterns("/**").excludePathPatterns("/hello");
}
springboot中默认的静态资源映射规则是通过url/webjars/** 去请求classpath:/WATE-INF/resources/webjars/下的内容.
WebMvcAutoConfiguration.java:中的默认规则如下:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
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));
}
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
.addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
}
如果我们需要自定义静态资源映射目录的话,只需重写addResourceHandlers方法即可。
addResoureHandler:指的是对外暴露的访问路径
addResourceLocations:指的是内部文件放置的目录
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/mySource/**").addResourceLocations("/my/");
}
通过转发到Servlet容器的“默认” Servlet,配置一个处理程序以委派未处理的请求。常见的用法是将映射到“ /”,从而覆盖Servlet容器对静态资源的默认处理。。
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
configurer.enable("defaultServletName");
重写此方法可以扩展视图解析器
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
InternalResourceViewResolver jspViewResolver = new InternalResourceViewResolver();
jspViewResolver.setPrefix("/myJsp/");
jspViewResolver.setSuffix(".jsp");
jspViewResolver.setViewNames("*");
registry.viewResolver(jspViewResolver);
}