Exceptions

如果在 请求映射过程中 发生异常或从 请求处理程序(如 **@Controller**)抛出异常,DispatcherServlet 会委托给一串 HandlerExceptionResolver Bean 来解决异常并提供替代处理,这通常是一个 错误响应

下表列出了可用的 HandlerExceptionResolver 实现:

HandlerExceptionResolver Description
SimpleMappingExceptionResolver 异常类名称和错误视图名称之间的映射。对于在浏览器应用程序中渲染错误页面非常有用。
DefaultHandlerExceptionResolver 解决由 Spring MVC 引发的异常,并将其映射为 HTTP 状态码。也请参见替代的 ResponseEntityExceptionHandler 和 REST API 异常
ResponseStatusExceptionResolver 解决带有 @ResponseStatus 注解的异常,并根据注解中的值将其映射到 HTTP 状态码。
ExceptionHandlerExceptionResolver 通过调用 @Controller 或 @ControllerAdvice 类中的 @ExceptionHandler 方法来解决异常问题。参见@ExceptionHandler 方法

解析器链

Chain of Resolvers

你可以通过在 Spring 配置中声明多个 HandlerExceptionResolver Bean 并根据需要设置它们的顺序属性来形成一个异常解析器链。顺序属性越高,异常解析器的位置就越晚

HandlerExceptionResolver 的契约规定,它可以返回:

  • ModelAndView:指向一个错误视图。
  • 一个空的 ModelAndView:如果异常在解析器中被处理。
  • null:如果异常仍未被解决,则为空,供后续的解析器尝试,如果异常仍在最后,则允许它冒泡到 Servlet 容器中。

MVC 配置 自动为默认的 Spring MVC 异常、@ResponseStatus注解的异常以及 @ExceptionHandler 方法的支持声明了内置的解析器。你可以自定义该列表或替换它。

容器错误页面

Container Error Page

如果一个异常仍然没有被任何 HandlerExceptionResolver 解决,因此,任其传播,或者如果响应状态被设置为错误状态(即 4xx,5xx),Servlet 容器可以在 HTML 中渲染一个默认的错误页面。为了定制容器的默认错误页面,你可以在 web.xml 中声明一个错误页面映射。下面的例子显示了如何做到这一点:

  1. <error-page>
  2. <location>/error</location>
  3. </error-page>

鉴于前面的例子,当一个异常冒出来或响应有错误状态时,Servlet 容器在容器内向配置的 URL(例如,/error)进行 ERROR 调度。然后由DispatcherServlet 进行处理,可能会将其映射到一个 @Controller,它可以被实现为返回一个带有模型的错误视图名称或渲染一个 JSON 响应,如下例所示:

  1. @RestController
  2. public class ErrorController {
  3. @RequestMapping(path = "/error")
  4. public Map<String, Object> handle(HttpServletRequest request) {
  5. Map<String, Object> map = new HashMap<String, Object>();
  6. map.put("status", request.getAttribute("javax.servlet.error.status_code"));
  7. map.put("reason", request.getAttribute("javax.servlet.error.message"));
  8. return map;
  9. }
  10. }

:::tips 暂时不知道如何让这个配置生效 :::