w3wp.exe 发生.net framework异常_DispatcherServlet - 异常处理

前言

  • 这里也许会有更好的阅读体验
  • 请大家看完以后一定要吐槽

1. Overview

当请求映射或处理请求时发生异常,DispatcherServlet 会将异常委派给 HandlerExceptionResolver 链来处理,然后响应一个错误信息。

1.1 几个特殊的 Bean

HandlerMapping 接口

  • 通过 @RequestMapping 将 Controller 中的方法注册到 DispatcherServlet 的一个 List 中

HandlerExecutionChain

  • 通过 HandlerMapping::getHandler 获取
  • 包含一个 handler,指定了请求 URL 匹配的 Controller 和方法
  • 包含 HandlerInterceptor 串

HandlerInterceptor 接口

  • 包含 preHandle、postHandle 和 afterCompletion 三个抽象方法
  • 用法有点像 Servlet 的 Filter,但是拦截器是基于 Java 反射,是 AOP 的一种运用,在这里是用来干啥的我也不太清楚

2. 异常处理过程 (POST 请求)

2.1 捕获异常

DispatcherServlet::doDispatch 通过 try / catch 捕获映射和处理请求的过程中抛出的异常

Exception dispatchException = null;
try {
    ...
    // 根据 RequestMapping 找到处理请求的 Bean 和方法
    HandlerExecutionChain mappedHandler = getHandler(processedRequest);
    // 由 HandlerAdapter 代理执行处理请求的方法
    HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
    mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
    ...
}
catch (Exception ex) {
    // 将异常赋值给 dispatchException
   dispatchException = ex;
}
// 处理响应(有无异常都是这个方法来处理)
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);

2.2 处理异常

在 processDispatchResult 方法中,DispatcherServlet 是用 HandlerExceptionResolverComposite 来处理异常的。而 HandlerExceptionResolverComposite 又通过一个 HandlerExceptionResolver 链来处理异常:

  1. ExceptionHandlerExceptionResolver - 根据异常类型匹配注解了 @ExceptionHandler 的方法来处理
  2. ResponseStatusExceptionResolver - 根据 @ResponseStatus 修改响应中的 HTTP status
  3. DefaultHandlerExceptionResolver - 根据异常类型返回 HTTP status 和 codes
// this.resolvers 中包含以上三个 HandlerExceptionResolver
for (HandlerExceptionResolver handlerExceptionResolver : this.resolvers) {
   ModelAndView mav = handlerExceptionResolver.resolveException(request, response, handler, ex);
   if (mav != null) {
      return mav;
   }
}

2.3 HandlerExceptionResolver 类关系图

59cd14b808d7137c0ca37949e88071c1.png
  • Ordered::getOrder 表示在异常处理链中 HandlerExceptionResolver 的执行顺序
  • HandlerExceptionResolverComposite 用了一个 List 来存放其它三个 HandlerExceptionResolver 的实现

通过 HandlerExceptionResolver::resolveException 可以找到各个实现中具体处理异常的方法:

  • ExceptionHandlerExceptionResolver::doResolveHandlerMethodException
  • ResponseStatusExceptionResolver::doResolveException
  • DefaultHandlerExceptionResolver::doResolveException

2.4 拦截器

除了 @ExceptionHandler 和 DefaultHandlerExceptionResolver 中的定义的异常类型,其它的异常不会被 HandlerExceptionResolver 链处理,例如 RuntimeException。

拦截器会将请求重新向到 /error。如果找不到 /error 的话就会返回错误:

{"status": 500, "error": "Internal Server Error", ...} 

拦截器这一块具体是怎么重定向到 /error 我就不知道了,没怎么看懂。

参考

  • https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值