Spring MVC 自定义异常类
自定义异常类能够更精确地表达业务错误,提高代码可读性和异常处理的可维护性。
基础自定义异常
Java
public class BusinessException extends RuntimeException {
private Integer code;
private String message;
public BusinessException(String message) {
super(message);
this.code = 500;
this.message = message;
}
public BusinessException(Integer code, String message) {
super(message);
this.code = code;
this.message = message;
}
public BusinessException(Integer code, String message, Throwable cause) {
super(message, cause);
this.code = code;
this.message = message;
}
public Integer getCode() {
return code;
}
@Override
public String getMessage() {
return message;
}
}
业务异常枚举设计
Java
public enum BusinessErrorCode {
// 用户相关 1xxx
USER_NOT_FOUND(1001, "用户不存在"),
USER_ALREADY_EXISTS(1002, "用户已存在"),
INVALID_CREDENTIALS(1003, "用户名或密码错误"),
ACCOUNT_DISABLED(1004, "账户已被禁用"),
// 订单相关 2xxx
ORDER_NOT_FOUND(2001, "订单不存在"),
ORDER_EXPIRED(2002, "订单已过期"),
ORDER_PAID(2003, "订单已支付"),
ORDER_CANCELED(2004, "订单已取消"),
// 商品相关 3xxx
PRODUCT_NOT_FOUND(3001, "商品不存在"),
PRODUCT_OUT_OF_STOCK(3002, "商品库存不足"),
PRODUCT_OFF_SHELF(3003, "商品已下架");
private final Integer code;
private final String message;
BusinessErrorCode(Integer code, String message) {
this.code = code;
this.message = message;
}
public Integer getCode() {
return code;
}
public String getMessage() {
return message;
}
}
基于枚举的异常类
Java
public class BusinessException extends RuntimeException {
private final Integer code;
private final String message;
public BusinessException(BusinessErrorCode errorCode) {
super(errorCode.getMessage());
this.code = errorCode.getCode();
this.message = errorCode.getMessage();
}
public BusinessException(BusinessErrorCode errorCode, String customMessage) {
super(customMessage);
this.code = errorCode.getCode();
this.message = customMessage;
}
public BusinessException(BusinessErrorCode errorCode, Throwable cause) {
super(errorCode.getMessage(), cause);
this.code = errorCode.getCode();
this.message = errorCode.getMessage();
}
public Integer getCode() {
return code;
}
@Override
public String getMessage() {
return message;
}
}
分类异常设计
Java
// 用户异常
public class UserException extends BusinessException {
public UserException(BusinessErrorCode errorCode) {
super(errorCode);
}
}
// 订单异常
public class OrderException extends BusinessException {
public OrderException(BusinessErrorCode errorCode) {
super(errorCode);
}
}
// 支付异常
public class PaymentException extends BusinessException {
public PaymentException(BusinessErrorCode errorCode) {
super(errorCode);
}
public PaymentException(BusinessErrorCode errorCode, String orderId) {
super(errorCode, errorCode.getMessage() + ", 订单号: " + orderId);
}
}
全局异常处理
Java
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(BusinessException.class)
public ResponseEntity<ApiResult<Void>> handleBusinessException(BusinessException e) {
log.warn("业务异常: code={}, message={}", e.getCode(), e.getMessage());
return ResponseEntity.status(e.getCode() < 500 ? e.getCode() : 500)
.body(ApiResult.error(e.getCode(), e.getMessage()));
}
@ExceptionHandler(UserException.class)
public ResponseEntity<ApiResult<Void>> handleUserException(UserException e) {
log.warn("用户业务异常: {}", e.getMessage());
return ResponseEntity.badRequest()
.body(ApiResult.error(e.getCode(), e.getMessage()));
}
@ExceptionHandler(OrderException.class)
public ResponseEntity<ApiResult<Void>> handleOrderException(OrderException e) {
log.warn("订单业务异常: {}", e.getMessage());
return ResponseEntity.badRequest()
.body(ApiResult.error(e.getCode(), e.getMessage()));
}
}
业务中使用
Java
@Service
public class UserService {
public User getUserById(Long id) {
User user = userRepository.findById(id);
if (user == null) {
throw new UserException(BusinessErrorCode.USER_NOT_FOUND);
}
return user;
}
public void login(String username, String password) {
User user = userRepository.findByUsername(username);
if (user == null) {
throw new UserException(BusinessErrorCode.INVALID_CREDENTIALS);
}
if (!user.isEnabled()) {
throw new UserException(BusinessErrorCode.ACCOUNT_DISABLED);
}
// 验证密码...
}
}
@Service
public class OrderService {
public void createOrder(OrderDTO orderDTO) {
Product product = productService.getById(orderDTO.getProductId());
if (product == null) {
throw new OrderException(BusinessErrorCode.PRODUCT_NOT_FOUND);
}
if (product.getStock() < orderDTO.getQuantity()) {
throw new OrderException(BusinessErrorCode.PRODUCT_OUT_OF_STOCK);
}
// 创建订单...
}
}
异常断言工具类
Java
public class AssertUtil {
public static void isTrue(boolean expression, BusinessErrorCode errorCode) {
if (!expression) {
throw new BusinessException(errorCode);
}
}
public static void isFalse(boolean expression, BusinessErrorCode errorCode) {
if (expression) {
throw new BusinessException(errorCode);
}
}
public static void notNull(Object object, BusinessErrorCode errorCode) {
if (object == null) {
throw new BusinessException(errorCode);
}
}
public static void notEmpty(String str, BusinessErrorCode errorCode) {
if (str == null || str.isEmpty()) {
throw new BusinessException(errorCode);
}
}
public static void notEmpty(Collection<?> collection, BusinessErrorCode errorCode) {
if (collection == null || collection.isEmpty()) {
throw new BusinessException(errorCode);
}
}
}
自定义异常应继承RuntimeException而非Exception,避免强制捕获。
要点总结
- 自定义异常继承RuntimeException,包含code和message属性
- 使用枚举统一管理错误码和错误信息
- 可按业务模块细分异常类型
- 全局异常处理器统一捕获处理
- 提供断言工具类简化异常抛出
📝 发现内容有误?点击此处直接编辑