能够给Controller加切面的机制都能变相的进行统一异常处理,比如之前通过 AOP 实现的全局统一的异常处理:Spring aop 统一异常处理和日志输出。
这里总结一下,其他常用的异常处理方式。
接下来主要介绍五种处理异常的方式:
HandlerExceptionResolver 是 Web 程序发生异常时, Spring 处理异常的接口,提供了一个抽象类和四个实现类:
四个实现类,是特定情况下可以选择,我们一般通过实现 HandlerExceptionResolver 接口或继承 AbstractHandlerExceptionResolver 抽象类来自定义异常处理。
@Component
public class ExceptionTest implements HandlerExceptionResolver{
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,Exception ex) {
System.out.println("This is exception handler method!");
return null;
}
}
用的比较多
@ExceptionHandler 可以单独使用,定义在某个 Controller 下,会针对当前 Controller 下的异常进行处理。
@RestController
public class DemoController{
//...比如对DemoController下的IllegalStateException异常进行处理
@ExceptionHandler({IllegalStateException.class})
public ModeAndView handleIllegalStateException(IllegalStateException ex){
System.out.println("This is exception handler method!");
return null;
}
}
然而更多的时候是与 @ControllerAdvice 搭配使用,用于统一处理处理 Controller 的异常。
xxxxxxxxxx @ControllerAdvicepublic class MyExceptionHandler{ @ExceptionHandler(Exception.class) public String exceptionHandle(Exception ex){ System.out.println("This is exception handler method!"); return null; }}java
@ControllerAdvice 也可以限定 Controller 的范围:
@ControllerAdvice(annotations = DemoController.class)
@ControllerAdvice("com.moke.controller")
@ControllerAdvice(assignableTypes = {DemoController1.class, DemoController2.class})
优先级:先处理 Controller 中的 @ExceptionHandler,再处理全局的@ExceptionHandler
相比去前面的全局异常处理,ResponseEntityExceptionHandler 类会帮我们处理一些 Spring 的自带异常。通过继承这个类,重写具体的方法来处理具体的异常,目前可以处理如下 15 种异常类型:
注:在继承ResponseEntityExceptionHandler类后,重写需要的异常处理方法后,除了处理过的异常,出现其他异常会返回空JSON
使用方法非常简单,直接 throw 就会返回参数信息:
@GetMapping("/getUser")
public ResponseEntity<String> getUser(Integer id) {
throw new ResponseStatusException(404, "查无此人");
}
也可搭配 @ControllerAdvice 使用。
一般用于处理401,404,500等异常错误,默认出现这些错误是没有提示信息的,通过实现ErrorController可以返回我们自定义的信息
@RestController
public class ExceptionController implements ErrorController {
/**
* 默认错误为/error,因为Spring的默认异常处理映射为/error
*/
private static final String path_default = "/error";
@Override
public String getErrorPath() {
return path_default;
}
@RequestMapping(path = path_default)
public Result error(HttpServletRequest request,HttpServletResponse response){
return new Result(response.getStatus(),"服务端异常!");//Result是自定义的结果类
}
}