自己踩到了一个很大的坑,这篇博客对这个大坑做一记录,希望对大家有所帮助。
1.静态资源失效问题
我在做登录的时候,实现了资源映射,MVC拦截器去拦截请求,但是配置之后,静态资源失效了。
代码如下:
@Configuration
public class MyMvcConfig extends WebMvcConfigurationSupport {
@Override
protected void addViewControllers(ViewControllerRegistry registry) {
//super.addViewControllers(registry);
//浏览器发送/pxj请求来到success页面
//registry.addViewController("/pxj").setViewName("success");
registry.addViewController("/").setViewName("login");
registry.addViewController("/index.html").setViewName("login");
registry.addViewController("/main.html").setViewName("index");
}
@Override
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**").excludePathPatterns("/index.html","/user/login","/","/**/*.css",
"/**/*.js","/static/**");
}
}
public class LoginHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object user = request.getSession().getAttribute("loginUser");
if(user == null){
//未登录,返回登录页
System.out.println("没有权限请先登录");
request.setAttribute("msg","没有权限请先登录");
request.getRequestDispatcher("/index.html").forward(request,response);
return false;
}else{
//已登录,放行请求
return true;
}
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
那么为什么会出现这种情况呢?一起看下SpringBoot自动配置源码:
WebMvcAutoConfiguration
@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 {
上述代码中有@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)这局,意思是:若是存在WebMvcConfigurationSupport类型的类,则自动配置失效。
========================================================
上面了解SpringMVC为何失效的原因,那么我们应该怎么进行扩展呢?
第一种方法:继承WebMvcConfigurationAdapter
WebMvcConfigurationAdapter 在spring boot 2.0被废弃以后,所以我们在这里就不用这个方法了。
第二种方法:实现WebMvcConfigurer
@Configuration
public class MvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("/login");
}
......
}
这样就不会影响自动配置了。那么为什么可以这样配置呢?再来看下WebMvcAutoConfiguration源码
以SpringBoot2.2.6来看下这样配置的原理。
1.springMVC自动配置类,若是WebMvcConfigurationSupport这个类型的类不存在,则自动配置生效。
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
@AutoConfigureOrder(-2147483638)
@AutoConfigureAfter({DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class})
public class WebMvcAutoConfiguration {
2.上面类中有如下配置类
@Configuration(proxyBeanMethods = false)
public static class EnableWebMvcConfiguration extends
DelegatingWebMvcConfiguration implements ResourceLoaderAware {
3.DelegatingWebMvcConfiguration 类型的类实现了这个WebMvcConfigurationSupport接口
@Configuration(proxyBeanMethods = false)
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
4.DelegatingWebMvcConfiguration类中有如下方法。注入所有的WebMvcConfigurer类型的类,将所有的WebMvcConfigurer相关的配置都来一起调用;
@Autowired(required = false)
public void setConfigurers(List<WebMvcConfigurer> configurers) {
if (!CollectionUtils.isEmpty(configurers)) {
this.configurers.addWebMvcConfigurers(configurers);
}
}
5.WebMvcConfigurerComposite实现类这个类,依次调用所有的WebMvcConfigurer类型的类。
class WebMvcConfigurerComposite implements WebMvcConfigurer {
public void addViewControllers(ViewControllerRegistry registry) {
Iterator var2 = this.delegates.iterator();
while(var2.hasNext()) {
WebMvcConfigurer delegate = (WebMvcConfigurer)var2.next();
delegate.addViewControllers(registry);
}
}
本文解决了一个在Spring Boot项目中常见的问题:配置MVC拦截器后静态资源失效。通过深入分析Spring Boot自动配置源码,提供了两种有效解决方案,帮助开发者避免此类陷阱。
2813

被折叠的 条评论
为什么被折叠?



