Java自定义业务异常类

一、类的作用

核心功能:

  1. 封装业务异常信息 - 包含错误码和错误消息

  2. 继承RuntimeException - 属于非受检异常,不需要强制捕获

  3. 统一异常格式 - 在整个应用中保持一致的异常处理方式

设计特点:

  • code: 自定义错误码,用于前端识别错误类型

  • message: 错误描述信息

  • 支持两种枚举类型(RespStatus和ResponseStatus)的异常构造

二、构造方法详解

java 复制代码
// 1. 指定错误码和消息
new BusinessException(400, "参数错误")

// 2. 使用RespStatus枚举(推荐)
new BusinessException(RespStatus.ERROR)

// 3. 仅提供消息,默认500错误码
new BusinessException("系统内部错误")

// 4. 带原始异常的构造
new BusinessException(400, "处理失败", originalException)

// 5. 使用ResponseStatus枚举
new BusinessException(ResponseStatus.SUCCESS)

// 6. 带异常的ResponseStatus
new BusinessException(ResponseStatus.ERROR, originalException)

三、实际应用示例

场景1:在Service层使用

java 复制代码
@Service
public class UserService {
    
    public User getUserById(Long id) {
        User user = userRepository.findById(id);
        if (user == null) {
            // 使用枚举方式
            throw new BusinessException(RespStatus.USER_NOT_FOUND);
            // 或使用代码+消息方式
            throw new BusinessException(404, "用户不存在");
        }
        return user;
    }
    
    public void updateSalary(Long userId, BigDecimal amount) {
        if (amount.compareTo(BigDecimal.ZERO) < 0) {
            throw new BusinessException(ResponseStatus.INVALID_PARAM);
        }
        // 业务逻辑...
    }
}

场景2:在Controller层处理

java 复制代码
@RestControllerAdvice
public class GlobalExceptionHandler {
    
    @ExceptionHandler(BusinessException.class)
    public Result<Void> handleBusinessException(BusinessException e) {
        return Result.error(e.getCode(), e.getMessage());
    }
    
    @ExceptionHandler(Exception.class)
    public Result<Void> handleOtherException(Exception e) {
        return Result.error(500, "系统异常");
    }
}

场景3:定义和使用枚举

java 复制代码
// RespStatus枚举示例
public enum RespStatus {
    SUCCESS(200, "成功"),
    ERROR(500, "系统错误"),
    USER_NOT_FOUND(404, "用户不存在"),
    PARAM_ERROR(400, "参数错误"),
    FORBIDDEN(403, "无权限访问");
    
    private final Integer code;
    private final String desc;
    
    // 构造方法、getter...
}

// 使用示例
public class OrderService {
    public void createOrder(OrderDTO dto) {
        if (dto.getAmount() <= 0) {
            throw new BusinessException(RespStatus.PARAM_ERROR);
        }
    }
}

四、最佳实践建议

1. 分层使用

java 复制代码
// Controller层:参数校验
@PostMapping("/create")
public Result create(@Valid @RequestBody UserDTO dto) {
    if (dto.getAge() < 18) {
        throw new BusinessException(400, "年龄必须大于18岁");
    }
}

// Service层:业务校验
public void transfer(Long from, Long to, BigDecimal amount) {
    Account fromAccount = accountRepository.findById(from);
    if (fromAccount.getBalance().compareTo(amount) < 0) {
        throw new BusinessException(ResponseStatus.INSUFFICIENT_BALANCE);
    }
}

// Repository层:建议使用原生异常
public User findUser(Long id) {
    return userRepository.findById(id)
        .orElseThrow(() -> new BusinessException(RespStatus.USER_NOT_FOUND));
}

2. 统一返回格式

java 复制代码
@Data
public class Result<T> {
    private Integer code;
    private String message;
    private T data;
    
    public static <T> Result<T> success(T data) {
        Result<T> result = new Result<>();
        result.setCode(200);
        result.setMessage("成功");
        result.setData(data);
        return result;
    }
    
    public static <T> Result<T> error(Integer code, String message) {
        Result<T> result = new Result<>();
        result.setCode(code);
        result.setMessage(message);
        return result;
    }
}

3. 创建业务异常工厂(可选)

java 复制代码
public class BusinessExceptionFactory {
    
    public static BusinessException userNotFound() {
        return new BusinessException(RespStatus.USER_NOT_FOUND);
    }
    
    public static BusinessException insufficientBalance() {
        return new BusinessException(400, "余额不足");
    }
    
    public static BusinessException parameterError(String field) {
        return new BusinessException(400, field + "参数错误");
    }
}
// 使用
throw BusinessExceptionFactory.userNotFound();

五、注意事项

  1. 不要滥用:仅在业务逻辑错误时使用,技术异常(如数据库连接失败)建议用原生异常

  2. 错误码规划

    • 4xx: 客户端错误(400参数错误、403无权限、404不存在)

    • 5xx: 服务端错误

  3. 国际化支持:如需多语言,可考虑扩展消息为消息键

  4. 日志记录:在全局异常处理器中记录异常日志

六、扩展建议

如果需要更丰富的功能,可以考虑:

java 复制代码
// 扩展类示例
public class EnhancedBusinessException extends BusinessException {
    private Map<String, Object> data;
    private String errorType;
    
    public EnhancedBusinessException(Integer code, String message) {
        super(code, message);
    }
    
    // 添加额外数据
    public EnhancedBusinessException withData(Map<String, Object> data) {
        this.data = data;
        return this;
    }
}

总结

这个**BusinessException** 类是业务异常的统一封装,通过:

  • 标准化错误码和消息格式

  • 支持多种构造方式

  • 便于全局异常处理

使用时遵循"业务异常用BusinessException,技术异常用原生异常"的原则,能显著提高代码的可维护性和异常处理的规范性。

相关推荐
鬼蛟8 分钟前
Spring————事务
android·java·spring
西门吹-禅40 分钟前
【sap fiori cds up error】
java·服务器·sap cap cds
敲代码的嘎仔1 小时前
Java后端面试——SSM框架面试题
java·面试·职场和发展·mybatis·ssm·springboot·八股
大傻^1 小时前
Spring AI Alibaba RAG实战:基于向量存储的检索增强生成
java·人工智能·spring
大傻^1 小时前
Spring AI Alibaba 快速入门:基于通义千问的AI应用开发环境搭建
java·人工智能·后端·spring·springai·springaialibaba
伯恩bourne1 小时前
Google Guava:Java 核心工具库的卓越之选
java·开发语言·guava
小王不爱笑1322 小时前
Spring 基础核心
java
心勤则明2 小时前
用 Spring AI Alibaba 打造智能查询增强引擎
java·人工智能·spring
Arva .2 小时前
Spring 的三级缓存,两级够吗
java·spring·缓存
爱喝一杯白开水2 小时前
Java 定时任务完全指南
java