1、springboot添加拦截器

1、springboot添加拦截器

1、实现HandlerInterceptor 接口
package com.mubai.interceptor;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 自定义拦截器.
 *
 * @author Mubai
 * @date 2023/5/22 17:51
 **/
@Slf4j
public class TestInterceptor implements HandlerInterceptor {

    /**
     * 目标方法执行之前
     *
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        log.info("testInterceptor=====preHandle======");
        String type = request.getParameter("type");
        if (type != null) {
            // 放行
            return true;
        }
        //    拦截服务.未登录,跳转到登录页
        return false;
    }

    /**
     * 目标方法执行完成之后
     *
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

        log.info("testInterceptor=====postHandle======");
    }

    /**
     * 页面渲染之后
     *
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

        log.info("testInterceptor=====afterCompletion======");
    }
}

2、配置拦截器
package com.mubai.config;

import com.mubai.interceptor.TestInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 配置拦截器.
 *
 * @author Mubai
 * @date 2023/5/22 17:55
 **/
@Configuration
public class AdminWebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new TestInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/", "/test");
    }
}

3、拦截器执行过程

1、根据当前请求,找到HandlerExecutionChain【可以处理请求的handler以及handler的所有 拦截器】

​ 2、先来顺序执行 所有拦截器的 preHandle方法

2、如果当前拦截器prehandler返回为true。则执行下一个拦截器的preHandle

3、如果当前拦截器返回为false。直接 倒序执行所有已经执行了的拦截器的 afterCompletion;

4、如果任何一个拦截器返回false。直接跳出不执行目标方法

5、所有拦截器都返回True。执行目标方法

6、倒序执行所有拦截器的postHandle方法。

7、前面的步骤有任何异常都会直接倒序触发 afterCompletion

8、页面成功渲染完成以后,也会倒序触发 afterCompletion

img
在这里插入图片描述

4、执行器底层原理
1、拦截器究竟添加到哪里,我们在项目中的如下地方打一个断点进去一探究尽

在这里插入图片描述
跟随断点,往前面找,发现在如下地方,他把所有的拦截器加入到了处理器映射器中
在这里插入图片描述2、接下来,我们看在请求目标资源时,怎么处理拦截的

1、我们发现他在DispatcherServlet的doDispatch方法中,发现在目标方法的前后调用了拦截器的三个方法,他先通过处理器映射器匹配到我们目标资源的拦截器链,
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Kuel1KoM-1684766699597)(/Users/qiguohui/Library/Application Support/typora-user-images/image-20230522220659674.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bukyxl3F-1684766699597)(/Users/qiguohui/Library/Application Support/typora-user-images/image-20230522222747491.png)]

我们点进去看一下mappedHandler.applyPreHandle(processedRequest, response)的具体实现逻辑,方法一目了然,遍历拦截器链,从下标0开始调用每一个连接器的前置处理方法,如果前置方法返回true,则interceptorIndex=i,同时i++,

在这里插入图片描述

如果返回为false,则会触发triggerAfterCompletion方法,调用所有执行完前置方法的过滤器,具体逻辑如下:

在这里插入图片描述

从方法可以看出,他从interceptorIndex值开始往前执行,执行完之后返回false,再到DispatcherServlet中,直接return;不会调用目标方法。

如果返回为true,他会再调用完目标方法之后,则会进入到DispatcherServlet后置处理器方法,该方法从执行器链的最后一个元素开始,往前执行,方法很简单,这里就不赘述了。

最后会执行到拦截器链的afterCompletion方法,从interceptorIndex往前执行,详细过程如下,这里的interceptorIndex=链的长度
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8u768hQZ-1684766699598)(/Users/qiguohui/Library/Application Support/typora-user-images/image-20230522224130541.png)]

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
在Spring Boot中添加拦截非常简单,只需要实现HandlerInterceptor接口,并通过@Configuration注解将其配置为一个Bean即可。 以下是一个示例: 1. 创建一个拦截类,实现HandlerInterceptor接口: ```java public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 在请求处理之前进行拦截,可以进行一些权限验证、日志记录等操作 return true; // 返回true表示继续执行请求处理,返回false表示拦截请求 } @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 { // 在请求处理完成之后进行拦截,可以进行一些资源清理等操作 } } ``` 2. 在配置类中添加拦截配置: ```java @Configuration public class WebMvcConfig implements WebMvcConfigurer { @Autowired private MyInterceptor myInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(myInterceptor).addPathPatterns("/**"); // 添加拦截并设置拦截路径 } } ``` 这样就完成了拦截添加。在addPathPatterns方法中,可以设置拦截的路径,例如"/user/**"表示拦截所有以"/user"开头的请求。 需要注意的是,如果需要在拦截中使用@Autowired注解注入其他Bean,需要在拦截类上加上@Component注解,使其成为一个Spring Bean。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值