全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-18 6 分钟 ✍️ juanwangdev

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属性
  • 使用枚举统一管理错误码和错误信息
  • 可按业务模块细分异常类型
  • 全局异常处理器统一捕获处理
  • 提供断言工具类简化异常抛出

📝 发现内容有误?点击此处直接编辑

← 上一篇 Spring MVC 多种异常处理
下一篇 → Spring MVC 返回JSON格式错误信息
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库