在 Spring Boot 中,统一异常处理是一种常见的做法,它可以让你集中处理应用程序中可能出现的各种异常,并为客户端提供一致的响应格式。
步骤 1: 创建异常类
首先,创建一些自定义异常类,以便在应用程序中抛出特定类型的异常。
// 自定义异常类
public class CustomException extends RuntimeException {private final int statusCode;private final String message;public CustomException(int statusCode, String message) {super(message);this.statusCode = statusCode;this.message = message;}public int getStatusCode() {return statusCode;}public String getMessage() {return message;}
}
步骤 2: 创建全局异常处理器
接下来,创建一个全局异常处理器来捕获并处理各种异常。
import org.springframework.http.HttpStatus;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;import java.util.HashMap;
import java.util.Map;@RestControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(CustomException.class)@ResponseStatus(HttpStatus.BAD_REQUEST)public Map<String, Object> handleCustomException(CustomException ex) {Map<String, Object> body = new HashMap<>();body.put("status", ex.getStatusCode());body.put("error", ex.getMessage());return body;}@ExceptionHandler(MethodArgumentNotValidException.class)@ResponseStatus(HttpStatus.BAD_REQUEST)public Map<String, Object> handleValidationExceptions(MethodArgumentNotValidException ex) {Map<String, Object> body = new HashMap<>();body.put("status", HttpStatus.BAD_REQUEST.value());body.put("errors", getValidationErrors(ex));return body;}private Map<String, String> getValidationErrors(MethodArgumentNotValidException ex) {Map<String, String> errors = new HashMap<>();ex.getBindingResult().getAllErrors().forEach((error) -> {String fieldName = ((FieldError) error).getField();String errorMessage = error.getDefaultMessage();errors.put(fieldName, errorMessage);});return errors;}
}
解释
-
CustomException
:- 这是一个自定义异常类,用于抛出自定义异常。
- 它包含了状态码和错误消息。
-
GlobalExceptionHandler
:- 使用
@RestControllerAdvice
注解来声明这是一个全局异常处理器。 @ExceptionHandler
注解用于捕获特定类型的异常。handleCustomException
方法处理CustomException
异常。handleValidationExceptions
方法处理MethodArgumentNotValidException
异常,这是由@Valid
或@Validated
触发的验证错误。
- 使用
步骤 3: 抛出异常
在控制器方法中,当需要抛出异常时,可以使用自定义异常类。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;import javax.validation.Valid;@RestController
public class UserController {@Autowiredprivate UserRepository userRepository;@PostMapping("/register")public ResponseEntity<String> register(@Valid @RequestBody User user) {if (userRepository.existsByUsername(user.getUsername())) {throw new CustomException(400, "用户名已存在");}userRepository.save(user);return ResponseEntity.ok("注册成功");}
}
测试
运行 Spring Boot 应用程序,并发送 POST 请求到 /register
端点,测试不同的输入情况:
-
正确的输入:
- 发送一个包含有效用户名、密码和电子邮件的 JSON 对象。
- 应该收到响应 “注册成功”。
-
错误的输入:
- 发送一个包含重复用户名或其他无效数据的 JSON 对象。
- 应该收到响应,显示验证错误信息。
-
抛出自定义异常:
- 尝试使用已经存在的用户名进行注册。
- 应该收到响应,显示 “用户名已存在” 的错误信息。
总结
通过上述步骤,您可以实现 Spring Boot 应用程序中的统一异常处理。具体步骤如下:
- 定义自定义异常类。
- 创建全局异常处理器类。
- 在控制器中抛出异常。
这样,无论何时在应用程序中发生异常,都可以通过统一的方式进行处理,确保客户端始终接收到一致的错误响应格式。