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

相关推荐
Adellle2 小时前
Java爬虫入门(2/5)
java·爬虫
JIngJaneIL2 小时前
基于Java+ vue图书管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
Github掘金计划2 小时前
开发者狂喜!GitHub 官方开源:支持 Copilot/Cursor,规范即代码,27k Star 封神!
java·python·kafka·github·copilot
Wpa.wk2 小时前
自动化测试-鼠标+键盘操作 - Actions高级控件
java·开发语言·测试工具·自动化·计算机外设·actions·高级控件
g***B7382 小时前
Java 的第三次跃迁:从企业级语言走向智能时代的通用计算引擎
java·开发语言
一 乐2 小时前
幼儿园管理|基于springboot + vue幼儿园管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端
JH灰色2 小时前
【大模型】-LangChain多模态输入和自定义输出
java·前端·langchain
JIngJaneIL2 小时前
基于Java + vue校园论坛系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端