作者简介:大家好,我是码炫码哥,前中兴通讯、美团架构师,现任某互联网公司CTO,兼职码炫课堂主讲源码系列专题
代表作:《jdk源码&多线程&高并发》,《深入tomcat源码解析》,《深入netty源码解析》,《深入dubbo源码解析》,《深入springboot源码解析》,《深入spring源码解析》,《深入redis源码解析》等
联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬。码炫课堂的个人空间-码炫码哥个人主页-面试,源码等
回答
Spring MVC 提供了三种方式来进行统一异常处理:
- 使用
@ExceptionHandler
:使用@ExceptionHandler
标注在 Controller 的方法上面,当 Controller 中的方法抛出指定异常时,Spring 会自动调用标记了@ExceptionHandler
的方法进行处理。但是该方式只对特定Controller 有效。 - 实现
HandlerExceptionResolver
接口:HandlerExceptionResolver
是 Spring MVC 提供的一个异常处理接口,它允许我们再应用层处理所有异常,当一个 Controller 抛出异常时,Spring 会通过HandlerExceptionResolver
来决定如何处理该异常,我们可以实现该接口来定制全局的异常处理逻辑。 - 使用
@ControllerAdvice
+@ExceptionHandler
:目前最主流的处理方式。@ControllerAdvice
允许我们定义一个全局异常处理器,结合@ExceptionHandler
,@ControllerAdvice
就可以捕获所有 Controller 中的异常并统一处理。
详解
使用 @ExceptionHandler
示例如下:
@Controller
public class SkJavaController {
@RequestMapping("/skjava")
public String skjava() {
if (true) {
throw new RuntimeException("抛个异常看看...");
}
return "success";
}
// 使用 @ExceptionHandler 注解处理 RuntimeException 异常
@ExceptionHandler(RuntimeException.class)
public ResponseEntity<String> handleRuntimeException(RuntimeException ex) {
return new ResponseEntity<>("发生了 RuntimeException: " + ex.getMessage(), HttpStatus.BAD_REQUEST);
}
}
当 skjava()
抛出 RuntimeException 异常时,Spring MVC 会 handleRuntimeException()
方法处理该异常,并返回一个带有错误信息和状态码的响应。但是这种方式至对特定的 Controller 有效。如果想要为整个应用提供全局异常处理,则需要使用下面两种方式。
当然,这种方式也不是一无是处,当我们只需要在某些特定的 Controller 中处理特定的异常时,@ExceptionHandler
还是非常合适的。