Spring Boot REST API移除try-catch,仅用@ExceptionHandler处理异常
移除API中所有try-catch,仅用@ExceptionHandler统一处理异常
完全可以通过全局异常处理器实现无try-catch的异常处理,你之前用@ExceptionHandler没生效,大概率是没配置全局生效的注解。以下是具体实现步骤:
1. 配置全局异常处理器(核心)
必须给异常处理类添加@RestControllerAdvice(针对REST API)或@ControllerAdvice注解,这样@ExceptionHandler才能全局生效(否则仅对当前Controller有效)。
示例代码:
@RestControllerAdvice public class GlobalExceptionHandler { // 处理自定义业务异常 @ExceptionHandler(BusinessException.class) public ResponseEntity<ErrorResponse> handleBusinessException(BusinessException ex) { ErrorResponse error = new ErrorResponse(ex.getCode(), ex.getMessage()); return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST); } // 处理参数校验异常 @ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity<ErrorResponse> handleValidationError(MethodArgumentNotValidException ex) { String errorMsg = ex.getBindingResult().getFieldErrors().stream() .map(err -> err.getField() + ": " + err.getDefaultMessage()) .collect(Collectors.joining(", ")); ErrorResponse error = new ErrorResponse("400", "参数错误:" + errorMsg); return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST); } // 兜底处理所有未捕获异常 @ExceptionHandler(Exception.class) public ResponseEntity<ErrorResponse> handleAllExceptions(Exception ex) { ErrorResponse error = new ErrorResponse("500", "服务器内部错误"); return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR); } } // 统一错误响应体 class ErrorResponse { private String code; private String message; public ErrorResponse(String code, String message) { this.code = code; this.message = message; } // getter、setter 省略 }
2. 移除业务代码中的try-catch
直接让异常向上抛出即可,无需在Controller/Service层捕获:
Controller层示例
@RestController @RequestMapping("/api/users") public class UserController { @Autowired private UserService userService; @GetMapping("/{id}") public ResponseEntity<User> getUserById(@PathVariable Long id) { // 无try-catch,异常直接抛给全局处理器 User user = userService.getUserById(id); return ResponseEntity.ok(user); } @PostMapping public ResponseEntity<User> createUser(@Valid @RequestBody UserRequest request) { User user = userService.createUser(request); return ResponseEntity.status(HttpStatus.CREATED).body(user); } }
Service层示例
@Service public class UserService { public User getUserById(Long id) { return userRepository.findById(id) .orElseThrow(() -> new BusinessException("404", "用户不存在")); } } // 自定义业务异常类 class BusinessException extends RuntimeException { private String code; public BusinessException(String code, String message) { super(message); this.code = code; } public String getCode() { return code; } }
3. 排查@ExceptionHandler不生效的常见原因
- 未添加
@RestControllerAdvice/@ControllerAdvice:单独的@ExceptionHandler仅在当前Controller范围内生效,无法全局捕获。 - 异常被中间层提前捕获:比如Filter、Interceptor中的try-catch会拦截异常,导致无法传递到全局处理器。
- 异常类型匹配错误:确保
@ExceptionHandler注解指定的异常类型与抛出的异常匹配(子类异常会优先匹配对应处理器)。
内容的提问来源于stack exchange,提问作者Aditya Mehta
相关产品推荐
相关产品推荐

