SpringBoot 2.4.5配置拦截器+访问静态资源 源码分析(已解决)

问题背景

之前跟着一个SpringBoot2版本的视频教程学习,但是在配置拦截器的时候,始终无法访问到静态资源。这里是原来的拦截器代码:

/**
 * 登录检查
 * 1.配置拦截器
 * 2.把配置放在容器中
 */
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
    /**
     * 方法执行前
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession session = request.getSession();
        log.info("preHandle: {}", request.getRequestURI());
        if (session.getAttribute("user")==null){
            //System.out.println("未登录");
            request.setAttribute("msg","未登录!");
            request.getRequestDispatcher("/login").forward(request, response);
            return false;
        }else{
            return true;//放行
        }
    }
    /**
     * 方法执行后
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("postHandle: {}", request.getRequestURI());
    }
    /**
     * 页面渲染后
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("afterCompletion: {}", request.getRequestURI());
    }
}

WebMvcConfigurer接口实现类里添加:

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**").excludePathPatterns("/","/login","/static/**"); //放行的请求
    }

目录结构如下:静态资源放在/static目录下面。
在这里插入图片描述
然后我发现配置拦截器之后,始终无法访问到静态资源。我把注意集中在addInterceptor方法,更改excludePathPatterns里面的路径,但是都没有取得满意的效果。以上这些都不需要动,(实际上,springMVC的拦截器路径怎么配,用SpringBoot就怎么配就可以,只是形式不同)。解决办法在下面。


解决方案

1.首先检查页面中的访问路径是否正确:我习惯在jsp里面写basePath,basePath可以解决很多路径访问错误的问题。
在HTML中引入thymeleaf名称空间:

<html lang="en" xmlns:th="http://www.thymeleaf.org">

使用thymeleaf写basePath:

<base th:href="${#request.getContextPath()}+'/'">

这样在HTML中引入css等文件都可以写成:

<link type="text/css" rel="stylesheet" href="static/css/xxx.css">

2.然后我尝试在application.properties中添加静态资源的访问路径

# spring.mvc.static-path-pattern = /static/**

发现问题解决。后来借鉴了一篇文章里面的方法,在WebMvcConfigurer 接口实现类里添加:

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //需要配置1:----------- 需要告知系统,这是要被当成静态文件的!
        //第一个方法设置访问路径前缀,第二个方法设置资源路径
        registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
    }

问题也能解决
WebMvcConfigurer完整配置如下

package indi.huishi.admin.config;

import indi.huishi.admin.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @Author: Huishi
 * @Date: 2021/4/28 0:23
 */
@Configuration
public class AdminWebConfig implements WebMvcConfigurer {
    /**
     * 添加静态资源文件,外部可以直接访问地址
     * https://www.cnblogs.com/kangkaii/p/9023751.html
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //需要配置1:----------- 需要告知系统,这是要被当成静态文件的!
        //第一个方法设置访问路径前缀,第二个方法设置资源路径
        registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
    }
    /**
     * 拦截所有请求,只放行负责登录的两个请求路径
     * /** 拦截所有,包括静态资源也会被拦截
     * /* 不包括静态资源的所有路径
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**").excludePathPatterns("/","/login","/static/**"); //放行的请求
    }
}


源码分析

然后我就想看看application.properties中添加静态资源的访问路径和重写配置类的区别。
1.把断点打在重写配置类的方法,首先执行接口实现类里自定义的addResourceHandler,然后会经过WebMvcAutoConfiguration.java执行内部定义好的两个addResourceHandler
在这里插入图片描述
走完这两步可以发现我们自定义配置的pathPatternslocationValues,和其他两个是并列的。
在这里插入图片描述
2.然后我试下配置文件的方式,比较下他们的差别。把重写的addResourceHandler注释掉,把配置文件那句话加回去,debug打在autoconfiguration里面。
在这里插入图片描述
最下方看到,配置里添加的static路径在mvcProperties中。这和预期是一致的,因为

@ConfigurationProperties(prefix = "spring.mvc")
public class WebMvcProperties {

向下运行到和刚才一样的位置。
在这里插入图片描述它执行的两个内部add方法会加入到registrations里面。其中下面那个里面会调用这个mvcProperties变量。看来关键就在这。
在这里插入图片描述
容易看到servletContext不为null。
在这里插入图片描述
发现这个add里面的registration发生了改变
在这里插入图片描述
所以这里执行完之后registration还是两个,只不过我们更改了后面那个的pathPattern。
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值