一、默认情况:DefaultHandlerExceptionResolver
DefaultHandlerExceptionResolver 是 DispatcherServlet 默认的错误处理类,它会把 Spring MVC 抛出的标准异常对应一个状态码写入到 response 中,并返回默认的错误页面。
如果应用是一个 RESTful API 或者需要自定义错误,可以实现 HandlerExceptionResolver 或者使用 ExceptionHandler 注解等方法。
默认状态下 Spring MVC 异常和状态码的对应关系表:
二、自定义情况
1、自定义错误页面
可以在 web.xml 中自定义错误状态码对应的错误页面:
<error-page>
<error-code>404</error-code>
<location>/WEB-INF/jsp/errors/404.jsp</location>
</error-page>
实际上 error-code
也可以是具体的异常类:
<error-page>
<error-code>java.lang.NullPointerException</error-code>
<location>/WEB-INF/jsp/errors/error.jsp</location>
</error-page>
2、自定义错误处理
Spring MVC 的文档里给出了多个自定义错误处理的方法,我在这里总结为以下几种。
(1)实现 HandlerExceptionResolver 接口
HandlerExceptionResolver 接口可以处理所有 Controller 映射
(mapping)或执行
(execution)时抛出的异常。
-
实现HandlerExceptionResolver 接口,实现
resolveException
方法,并返回一个ModelAndView
。方法中的参数Exception
,就是要处理的异常,可以在方法体中判断异常的类型,采取不同的措施。 -
SimpleMappingExceptionResolver 是一个 HandlerExceptionResolver 的实现类,它可以把 Exception 和 View 一一对应,对不同的异常返回不同的页面。它的内部存放了一个 Properties,存储对应关系。
(2)@ExceptionHandler注解
ExceptionHandler 给 RESTful API 提供了错误处理方法。它的 Value
属性可以被设置为一个或一组异常类型——即方法体要处理的异常。
它可以被用在 @Controller 或 @ControllerAdvice 注解的类的方法上,当用在@Controller 方法上时,它会处理这个 Controller 中抛出的异常。
@Controller
public class SimpleController {
@ExceptionHandler(IOException.class)
public ResponseEntity<String> handleIOException(IOException ex) {
// prepare responseEntity
return responseEntity;
}
}
(3)@ControllerAdvice @RestControllerAdvice
使用 @ControllerAdvice 注解的类可以包含 @ExceptionHandler、@InitBinder 或 @ModelAttribute 注解的方法,它可以被 Spring MVC 自动发现和注册,可以处理所有 Controller 中用 @RequestMapping 的方法。
它也可以被限定只处理某些特定 Controller 的异常:
// 限定为 @RestController 注解的方法
@ControllerAdvice(annotations = RestController.class)
public class AnnotationAdvice {}
// 限定为指定包中的 Controller
@ControllerAdvice("org.example.controllers")
public class BasePackageAdvice {}
// 限定为指定的类
@ControllerAdvice(assignableTypes = {ControllerInterface.class, AbstractController.class})
public class AssignableTypesAdvice {}