Spring Web MVC对异常处理有着完善的支持,我们可以捕获控制器中抛出的任何异常,然后按照异常类型将异常信息映射到某个视图文件,向用户显示对应的信息。
@ExceptionHandler
最简单的办法就是使用@ExceptionHandler注解。它可以定义到一个控制器中,处理该控制器抛出的异常。@ExceptionHandler注解接受一个Class,指定捕获哪个异常。如果不指定这个值,则捕获方法参数列表中的所有异常。
@Controller
public class ExceptionController {
@ExceptionHandler(IOException.class)
public String handleException(IOException exception, Model model) {
model.addAttribute("message", exception.getMessage());
model.addAttribute("detail", exception);
return "exception";
}
@RequestMapping("/throw")
public String throwException() throws IOException {
if (true)
throw new IOException("蛋疼,遇到了一个IO错误");
return "exception";
}
}
该注解标注的方法也可以用于控制器通知(ControllerAdvice),应用到多个控制器上。
异常解析器
另外一种异常处理办法就是使用异常解析器。我们可以使用 SimpleMappingExceptionResolver
将异常类型和异常视图关联起来。也可以自己实现一个HandlerExceptionResolver
用于处理异常。使用方法可以参考这篇博客Spring MVC 系统异常处理方式及性能对比。
Spring默认情况下也会注册一个异常解析器DefaultHandlerExceptionResolver
,将Spring异常映射到4XX和5XX错误,详情参见Spring参考文档 22.11.3. Handling Standard Spring MVC Exceptions
使用@ResponseStatus注解业务异常
我们的业务代码的异常可以使用@ResponseStatus注解。当这样的异常抛出时,ResponseStatusExceptionResolver
会捕获这些异常并设置相应的错误代码。Spring默认会注册一个ResponseStatusExceptionResolver
,我们不需要手动设置即可使用。
@ResponseStatus(HttpStatus.NOT_FOUND)
public class MyCustomException extends RuntimeException {
public MyCustomException() {
super();
}
public MyCustomException(String msg) {
super(msg);
}
}
自定义Servlet容器错误页面
我们可以直接在web.xml
中定义Servlet容器的错误页面。如果使用Servlet 3.0容器的话,如果不指定错误类型,那么该页面会作为默认错误页面来应用。在Spring Web MVC中,该页面不仅可以是一个HTML或JSP页面,也可以是控制器中某个处理方法接受的URL。
<error-page>
<location>/error</location>
</error-page>