5月29日 01:37

Spring Boot 中如何实现全局异常处理?

Spring Boot 通过 @RestControllerAdvice + @ExceptionHandler 实现全局异常处理。前者是 AOP 组件,拦截所有 Controller 抛出的异常;后者按异常类型匹配处理方法,返回统一的响应体。典型做法是定义自定义 BusinessException 携带错误码和消息,在异常处理类中分别处理业务异常、参数校验异常(MethodArgumentNotValidException)和兜底异常(Exception),对外返回结构化的错误响应,对内记录日志并隐藏堆栈细节。RFC 7807 的 application/problem+json 是业界推荐的错误响应格式。

追问

  • @RestControllerAdvice 和 @ControllerAdvice 有何区别? 前者是后者的 @ResponseBody 组合注解,方法返回值直接序列化为 JSON;后者适用于返回 ModelAndView 的传统 MVC 场景。
  • 多个 @ExceptionHandler 匹配同一个异常时如何选择? Spring 选择异常类型最具体的那个方法,即继承链中最靠近抛出异常类型的处理器优先。
  • 如何处理 404 异常? 默认 Spring Boot 不抛出 404 异常而是返回白标签页,需设置 throw-exception-if-no-handler-found=true 并关闭 add-mappings=false,再用 @ExceptionHandler(NoHandlerFoundException.class) 捕获。
  • BusinessException 为什么用 RuntimeException 而非 Checked Exception? 避免 try-catch 侵入业务代码,全局处理器统一兜底,保持代码整洁。
  • 参数校验异常 MethodArgumentNotValidException 和 ConstraintViolationException 分别在何时触发? 前者发生在 @RequestBody + @Valid 校验请求体时,后者发生在 @RequestParam + @Validated 校验单参数时。

写段代码

java
@RestControllerAdvice public class GlobalExHandler { @ExceptionHandler(BusinessException.class) public ResponseEntity<Result<Void>> onBiz(BusinessException e) { return ResponseEntity.badRequest().body(Result.error(e.getCode(), e.getMessage())); } @ExceptionHandler(Exception.class) public ResponseEntity<Result<Void>> onEx(Exception e) { return ResponseEntity.status(500).body(Result.error(500, "系统繁忙")); } }
标签:Spring Boot