Spring MVC 的异常解析
-
核⼼接⼝
- HandlerExceptionResolver
-
实现类
- SimpleMappingExceptionResolver
- DefaultHandlerExceptionResolver
- ResponseStatusExceptionResolver
- ExceptionHandlerExceptionResolver
异常解析器
https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-exceptionhandlers
如果在请求映射期间发生异常或从请求处理程序(例如@Controller)抛出异常,DispatcherServlet将委托给HandlerExceptionResolver bean链来解决异常并提供替代处理,这通常是一个错误响应。
下表列出了可用的HandlerExceptionResolver实现:
异常处理解析器 | 描述 |
---|---|
SimpleMappingExceptionResolver | 异常类名和错误视图名之间的映射。用于在浏览器应用程序中呈现错误页面。 |
DefaultHandlerExceptionResolver | 解决Spring MVC引发的异常,并将它们映射到HTTP状态码。参见可选的ResponseEntityExceptionHandler和REST API exceptions。 |
ResponseStatusExceptionResolver | 使用@ResponseStatus注解解决异常,并基于注解中的值将其映射到HTTP状态码 |
ExceptionHandlerExceptionResolver | 通过调用@Controller或@ControllerAdvice类中的@ExceptionHandler方法来解决异常。参见@ExceptionHandler methods。 |
解析器链
您可以通过在Spring配置中声明多个HandlerExceptionResolver
bean
并根据需要设置它们的order
属性来形成异常解析器链。order
属性越高,异常解析器的位置越晚。
HandlerExceptionResolver的约定/规定指定它可以返回:
- 指向错误视图的ModelAndView。
- 如果异常是在解析器中处理的,则为空的ModelAndView。
- 如果异常仍然未解决,则为null,以便后续的解析器尝试;如果异常在结束时仍然存在,则允许它向上传递到Servlet容器。
MVC Config 会自动为默认的Spring MVC异常、@ResponseStatus
注解异常以及对@ExceptionHandler
方法的支持声明内置解析器。您可以自定义该列表或替换它。
容器的错误页面
如果任何HandlerExceptionResolver
仍然无法解析异常,以致让其传播,或者将响应状态设置为错误状态(即4xx, 5xx), Servlet容器可以用HTML呈现默认的错误页面。要自定义容器的默认错误页面,可以在web.xml中声明一个错误页面映射。下面的例子展示了如何做到这一点:
<error-page>
<location>/error</location>
</error-page>
对于前面的示例,当出现异常或响应具有错误状态时,Servlet容器在容器内向配置的URL(例如/error
)发出ERROR分派。然后DispatcherServlet
对其进行处理,可能将其映射到@Controller
,它可以被实现为返回带有模型的错误视图名或呈现JSON响应,如下面的示例所示:
@RestController
public class ErrorController {
@RequestMapping(path = "/error")
public Map<String, Object> handle(HttpServletRequest request) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("status", request.getAttribute("javax.servlet.error.status_code"));
map.put("reason", request.getAttribute("javax.servlet.error.message"));
return map;
}
}
Servlet API不提供在Java中创建错误页面映射的方法。但是,可以同时使用WebApplicationInitializer和最小的web.xml。