测试HTTP要求:
日志输出如下:解释IllegalRequestExceptionHandler未生效。

why? 这就须要精通Spring非常处理流程了。
解析当所有Filter被实行完毕,Spring才会处理Servlet干系,而DispatcherServlet才是全体Servlet处理核心,它是前端掌握器设计模式,供应 Spring Web MVC 的集中访问点并卖力职责的分派。
在这,Spring处理了要乞降处理器的对应关系及统一非常处理。
Filter内非常无法被统一处理,便是由于非常处理发生在 DispatcherServlet#doDispatch()
但此时,过滤器已全部实行完。
Spring非常统一处理ControllerAdvice如何被Spring加载并对外暴露?WebMvcConfigurationSupport#handlerExceptionResolver()实例化并注册一个ExceptionHandlerExceptionResolver 的实例
终极按下图调用栈,Spring 实例化了ExceptionHandlerExceptionResolver类。
ExceptionHandlerExceptionResolver实现了InitializingBean
重写 afterPropertiesSet()
initExceptionHandlerAdviceCache
完成所有 ControllerAdvice 中的ExceptionHandler 初始化:查找所有 @ControllerAdvice 表明的 Bean,把它们放入exceptionHandlerAdviceCache。 这里即指自定义的IllegalRequestExceptionHandler
所有被 @ControllerAdvice 表明的非常处理器,都会在 ExceptionHandlerExceptionResolver 实例化时自动扫描并装载在其exceptionHandlerAdviceCache。
initHandlerExceptionResolvers当第一次要求发生时,DispatcherServlet#initHandlerExceptionResolvers() 将获取所有注册到 Spring 的 HandlerExceptionResolver 实例(ExceptionHandlerExceptionResolver正是),存到handlerExceptionResolvers
ControllerAdvice如何被Spring消费并处理非常?DispatcherServletdoDispatch()实行用户要求时,当查找、实行要求对应的 handler 过程中非常时:
会把非常值赋给 dispatchException再移交 processDispatchResult()processDispatchResult当Exception非空时,连续移交
processHandlerException从 handlerExceptionResolvers 获取有效的非常解析器以解析非常。
这里的 handlerExceptionResolvers 一定包含声明的IllegalRequestExceptionHandler#IllegalRequestException 的非常处理器的 ExceptionHandlerExceptionResolver 包装类。
改动为利用到 Spring MVC 的非常处理机制,改造Filter:
手动捕获非常将非常通过 HandlerExceptionResolver 进行解析处理据此,修正 PermissionFilter,注入 HandlerExceptionResolver:
然后,在 doFilter 捕获非常并移交 HandlerExceptionResolver:
现在再用缺点 Token 要求,日志输出如下:
相应体: