Spring注解@RestControllerAdvice
实战之自定义异常篇
在构建RESTful API时,异常处理是一个非常重要的环节。一个优雅且有效的异常处理机制不仅能提高系统的健壮性,还能为客户端提供清晰明了的错误反馈。Spring框架中的@RestControllerAdvice
注解为我们提供了一个非常方便的方式来全局处理RESTful API中的异常。本文将介绍如何使用@RestControllerAdvice
来实战自定义异常处理。
自定义异常类
首先,我们需要定义一些自定义的异常类,用于表示API中可能发生的特定错误。
// 自定义异常基类
public class CustomException extends RuntimeException {
private int errorCode;
private String errorMessage;
public CustomException(int errorCode, String errorMessage) {
super(errorMessage);
this.errorCode = errorCode;
this.errorMessage = errorMessage;
}
// getter和setter方法
// ...
}
// 示例自定义异常
public class UserNotFoundException extends CustomException {
public UserNotFoundException(String message) {
super(404, "User not found: " + message);
}
}
// 另一个示例自定义异常
public class InvalidRequestException extends CustomException {
public InvalidRequestException(String message) {
super(400, "Invalid request: " + message);
}
}
使用@RestControllerAdvice
处理异常
接下来,我们使用@RestControllerAdvice
注解来创建一个全局异常处理器。
@RestControllerAdvice
public class GlobalExceptionHandler {
// 处理自定义异常
@ExceptionHandler(value = CustomException.class)
public ResponseEntity<Object> handleCustomException(CustomException e) {
// 构建错误响应体
Map<String, Object> errorResponse = new HashMap<>();
errorResponse.put("code", e.getErrorCode());
errorResponse.put("message", e.getErrorMessage());
// 返回错误响应
return new ResponseEntity<>(errorResponse, HttpStatus.valueOf(e.getErrorCode()));
}
// 处理其他异常(可选)
@ExceptionHandler(value = Exception.class)
public ResponseEntity<Object> handleGenericException(Exception e) {
// 记录日志或执行其他操作
// ...
// 构建通用错误响应体
Map<String, Object> errorResponse = new HashMap<>();
errorResponse.put("code", 500);
errorResponse.put("message", "Internal server error");
// 返回错误响应
return new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
在这个例子中,我们定义了两个@ExceptionHandler
方法。第一个方法专门用于处理自定义的CustomException
异常,它会根据异常中携带的错误码和错误信息来构建响应体。第二个方法是通用的异常处理器,用于处理其他未被特定处理的异常。
实战应用
在Controller层中,当遇到异常情况时,我们可以直接抛出自定义的异常。
@RestController
@RequestMapping("/users")
public class UserController {
// 假设有一个UserService
@Autowired
private UserService userService;
@GetMapping("/{id}")
public User getUserById(@PathVariable Long id) {
User user = userService.findById(id);
if (user == null) {
// 抛出自定义异常
throw new UserNotFoundException("User with ID " + id + " not found");
}
return user;
}
// 其他接口...
}
当用户请求一个不存在的用户ID时,UserController
会抛出一个UserNotFoundException
异常。由于我们已经在GlobalExceptionHandler
中为这个异常定义了处理方法,Spring会自动调用该方法来处理这个异常,并返回相应的错误响应给客户端。
总结
通过使用@RestControllerAdvice
和自定义异常类,我们可以轻松地实现RESTful API中的全局异常处理。这种方式不仅提高了代码的可读性和可维护性,还能为客户端提供清晰明了的错误反馈。在实际项目中,建议根据业务需求定义多个自定义异常类,并在GlobalExceptionHandler
中为它们分别定义处理方法。