Spring提供了多种方式将异常转换为特定的响应:
- 特定的Spring异常会自动映射为指定的HTTP响应状态码,如下面的表1所示。
- 抛出自定义异常并在异常类上可以添加@ResponseStatus注解,将异常映射为某一种状态码,然后再通过配置专门的错误页(可以在web.xml中使用<error-page>标签进行配置)进行处理,如下面的代码1所示。
- 在Controller中添加一个或多个用于处理异常的方法并在方法上用@ExceptionHandler加以注解,并指明该方法可以处理的异常类型,该方法可以返回错误视图的视图名或者返回ModelAndView对象,如下面代码2所示。
- 如果多个控制器有公共的异常需要统一处理,那么可以通过@ControllerAdvice为控制器写一个处理异常的Advice,如下面代码3所示。
表1 Spring默认异常对应的HTTP响应状态码
Spring异常 | HTTP响应状态码 |
BindException | 400 - Bad Request |
ConversionNotSupportedException | 500 - Internal Server Error |
HttpMediaTypeNotAcceptableException | 406 - Not Acceptable |
HttpMediaTypeNotSupportedException | 415 - Unsupported Media Type |
HttpMessageNotReadableException | 400 - Bad Request |
HttpMessageNotWritableException | 500 - Internal Server Error |
HttpRequestMethodNotSupportedException | 405 - Method Not Allowed |
MethodArgumentNotValidException | 400 - Bad Request |
MissingServletRequestParameterException | 400 - Bad Request |
MissingServletRequestPartException | 400 - Bad Request |
NoSuchRequestHandlingMethodException | 404 - Not Found |
TypeMismatchException | 400 - Bad Request |
代码1 使用@ResponseStatus注解将异常映射为响应状态码
@ResponseStatus(code = HttpStatus.NOT_FOUND, reason = "没有这样的员工")
public class NoSuchEmployeeException extends RuntimeException {
// ...
}
<web-app>
<!-- ... -->
<error-page>
<error-code>404</error-code>
<location>/404.html</location>
</error-page>
</web-app>
代码2 使用@ExceptionHandler指定处理异常的方法和异常类型
@Controller
public class EmpController {
@ExceptionHandler(java.lang.Exception.class)
public String handleRE(Model model, Exception ex) {
model.addAttribute("hint", ex.getMessage());
return "error";
}
// ...
}
代码3 定义专门用于异常处理的Advice
@ControllerAdvice
public class ControllerExceptionAdvice {
@ExceptionHandler(java.lang.Exception.class)
public ModelAndView handleRE(Model model, Exception ex) {
ModelAndView mav = new ModelAndView("error");
mav.addObject("hint", ex.getMessage());
return mav;
}
}
使用Spring提供这几种声明式异常处理,Web项目中的异常处理就变得so easy了!