Insight HandlerInterceptor 与@ExceptionHandler 的执行顺序

Insight HandlerInterceptor 与@ExceptionHandler 的执行顺序

问题起源:项目中HandlerInterceptor preHandle方法会把登录的用户信息存储在ThreadLocal,方便请求逻辑中获取,

afterCompletion方法中会remove。当发生异常时,想通过@ExceptionHandler打印当前的用户名,还能拿到用户信息吗?

概念明确

  • HandlerInterceptor 请求拦截器,允许自定义处理程序执行链的工作流接口。afterCompletion方法,完成请求处理后回调,that is,渲染视图后回调。
  • ExceptionHandler 用于处理特定处理程序类或方法中的异常的注解,主要在Servlet环境中使用,根据异常的类型进行映射。涉及的类有:,
  • ExceptionHandlerMethodResolver 扫描发现ExceptionHandler 注解的方法,并注册到mappedMethods
  • ExceptionHandlerExceptionResolver 通过@ExceptionHandler方法解析异常,根据如下的UML得知,最终会以HandlerExceptionResolver接口的形式,在DispatcherServlet中调用。

在这里插入图片描述

源码

// mvc请求处理入口
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
	try {
		Exception dispatchException = null;
		try {
			mappedHandler = getHandler(processedRequest);
            // 登录校验和用户信息的缓存就是在此执行
            if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                return;
			}

			// Actually invoke the handler.
			mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
			// 注意,业务发生异常,postHandle 是不会执行的
			mappedHandler.applyPostHandle(processedRequest, response, mv);
		}
		catch (Exception ex) {
			dispatchException = ex;
		}
        // 返回结果处理,返回ModelAndView,包括Exception 处理,参考processHandlerException
		processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
	}
	catch (Exception ex) {
        // 用户信息ThreadLocal 是在此remove 的
		triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
	}
}

结论

可以在请求发生异常时,在ExceptionHandler 中可以拿到用户信息

这样就很方便根据打印的日志定位和排查问题。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值