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,技术异常用原生异常"的原则,能显著提高代码的可维护性和异常处理的规范性。

相关推荐
元Y亨H15 小时前
Nacos - 服务发现
java·微服务
微露清风15 小时前
系统性学习C++-第十八讲-封装红黑树实现myset与mymap
java·c++·学习
dasi022715 小时前
Java趣闻
java
阿波罗尼亚16 小时前
Tcp SSE Utils
android·java·tcp/ip
susu108301891116 小时前
springboot3.5.8整合minio8.5.9
java·springboot
不知道累,只知道类16 小时前
深入理解 Java 虚拟线程 (Project Loom)
java·开发语言
myzshare17 小时前
实战分享:我是如何用SSM框架开发出一个完整项目的
java·mysql·spring cloud·微信小程序
Chan1617 小时前
【 Java八股文面试 | JavaSE篇 】
java·jvm·spring boot·面试·java-ee·八股
wen__xvn17 小时前
代码随想录算法训练营DAY10第五章 栈与队列part01
java·前端·算法
独自破碎E17 小时前
解释一下NIO、BIO、AIO
java·开发语言·nio