SpringBoot拦截器使用

拦截器接口HandlerInterceptor

HandlerInterceptor中的方法方法
public interface HandlerInterceptor {
  //具体handler执行前的拦截器,boolean返回是否进行拦截
    default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
    }

  //handler正常执行完后的逻辑,不实现拦截,可以对modelAndView操作。
    default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
    }

  //拦截器放行后必定执行该方法,可能正常执行,可能异常捕获执行。
    default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
    }
}
执行流程
	MVC执行流程中拦截器为我们提供方法的执行位置
try{
 				ModelAndView mv = null;
                Object dispatchException = null;
try{
/**
......
*/
  			//前置拦截器返回false,return
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
            return;
        }

  			//执行具体的handler方法逻辑
        mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

     /**
     ........
     */
  			//执行后置拦截器,传入modelAndView
        mappedHandler.applyPostHandle(processedRequest, response, mv);
    } catch (Exception var20) {
        dispatchException = var20;
    } catch (Throwable var21) {
        dispatchException = new NestedServletException("Handler dispatch failed", var21);
    }

			//无异常正常执行afterCompletion
    this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
}
			//出现异常捕获执行aferComletion
} catch (Exception var22) {
    this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22);
}
注意!

​    前后端分离项目,controller返回Json对象时,执行handler.handle时,前端调用已经结束,结果已经返回,此时modelAndView为空

Demo验证
Controller.java
	接口测试
@RestController
@RequestMapping("/fht")
public class LoginController {

  	@GetMapping("exception")
    public String exception(){
        int i = 10/0;
        return "exception";
    }

    @GetMapping("false")
    public String falseTest(){
        return "false";
    }

    @GetMapping("normal")
    public String normal() {
        return "normal";
    }
MyInterceptor.java
	我们自己的拦截器,需要实现HandlerInterceptor接口。
/**
自定义拦截器,实现HandlerInterceptor接口
*/
@Slf4j
public class MyInterceptor implements HandlerInterceptor {
    
  /**
  测试只拦截URI为false的请求
  */
     @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("拦截器preprepre执行");
        if (handler instanceof HandlerMethod && "/fht/false".equals(request.getRequestURI())) {
            HandlerMethod my = (HandlerMethod) handler;
            log.info("被拦截");
            return false;
        }
        return true;
    }
  /**
  测试查看modelAndView内容
  */
  @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("拦截器postpostpost执行");
        log.info("modelAndView是:{}", modelAndView);
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

  /**
  异常不验证了,一般异常都被捕获,这里都为null
  */
  @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("===afterCompletion,执行");
        if(ex ==null){
            log.info("无异常");
        }else {
            log.info("异常:{}",ex.getMessage());
        }
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}
MyMvcConfig.java
	将我们的拦截器注册到MVC的容器中,需要实现WebMvcConfigurer,重写addInterceptors
/**
自定义MVC配置类添加自定义MyInterceptor拦截器。
*/
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

    @Bean
    public HandlerInterceptor handlerInterceptor(){
        return new MyInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        InterceptorRegistration interceptor = registry.addInterceptor(handlerInterceptor());
      //配置拦截路径,不配置默认为 **,拦截所有
        interceptor.addPathPatterns("/fht/**")
          //不拦截路径
                .excludePathPatterns("/fht/test");
    }
}

验证执行流程
1.正常执行不拦截
  • URL: http://localhost:8080/fht/test

  • 打印结果: 在这里插入图片描述

​     结论: pre ->post ->after


2.被拦截
  • URL: http://localhost:8080/fht/false
  • 打印结果:在这里插入图片描述

​     结论: 只执行pre


3.出现异常被全局捕获
  • **URL:**http://localhost:8080/fht/exception
  • 打印结果:在这里插入图片描述

​     结论:不执行post,异常被全局异常处理,afterCompletion 中传入的 Exception 为 null



MVC执行流程中返回结果的处理

在这里插入图片描述

    preHadnler 和 postHandler打断点,debug运行后输入URL,在 preHandle 断点时浏览器在等结果,在 postHandle 时,结果已经返回,此时modelAndView是空的,结果已经被 JSON 处理器处理通过response.flush返回给客户端了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值