一、最简版本(适合新手)
java
import lombok.Getter;
/**
* 业务异常 - 最简单版本
*/
@Getter
public class BusinessException extends RuntimeException {
private final Integer code; // 错误码
// 构造方法1:指定错误码和消息
public BusinessException(Integer code, String message) {
super(message);
this.code = code;
}
// 构造方法2:只传消息,默认500错误码
public BusinessException(String message) {
this(500, message);
}
}
二、稍微丰富版本(推荐)
java
import lombok.Getter;
/**
* 业务异常 - 常用版本
*/
@Getter
public class BusinessException extends RuntimeException {
private final Integer code;
// 常用状态码定义
public static final Integer BAD_REQUEST = 400; // 请求参数错误
public static final Integer UNAUTHORIZED = 401; // 未授权
public static final Integer FORBIDDEN = 403; // 禁止访问
public static final Integer NOT_FOUND = 404; // 资源不存在
// 常用构造方法
public BusinessException(Integer code, String message) {
super(message);
this.code = code;
}
public BusinessException(String message) {
this(500, message);
}
// 快速创建方法(静态工厂方法)
public static BusinessException badRequest(String message) {
return new BusinessException(BAD_REQUEST, message);
}
public static BusinessException notFound(String resourceName) {
return new BusinessException(NOT_FOUND, resourceName + "不存在");
}
public static BusinessException forbidden() {
return new BusinessException(FORBIDDEN, "无权限访问");
}
}
三、配合枚举使用
java
// 1. 先定义错误枚举
@Getter
public enum ErrorCode {
SUCCESS(200, "成功"),
PARAM_ERROR(400, "参数错误"),
UNAUTHORIZED(401, "未登录"),
FORBIDDEN(403, "无权限"),
NOT_FOUND(404, "资源不存在"),
USER_NOT_FOUND(40401, "用户不存在"),
SYSTEM_ERROR(500, "系统错误");
private final Integer code;
private final String message;
ErrorCode(Integer code, String message) {
this.code = code;
this.message = message;
}
}
// 2. 修改异常类
@Getter
public class BusinessException extends RuntimeException {
private final Integer code;
// 使用枚举构造
public BusinessException(ErrorCode errorCode) {
super(errorCode.getMessage());
this.code = errorCode.getCode();
}
// 自定义消息
public BusinessException(ErrorCode errorCode, String customMessage) {
super(customMessage);
this.code = errorCode.getCode();
}
}
四、实际使用例子
java
@Service
public class UserService {
public User getUserById(Long id) {
User user = userRepository.findById(id);
// 情况1:直接抛异常
if (user == null) {
throw new BusinessException(404, "用户不存在");
}
// 情况2:使用快速方法
if (user.getStatus() == 0) {
throw BusinessException.forbidden();
}
// 情况3:使用枚举
if (user.getBalance() < 0) {
throw new BusinessException(ErrorCode.PARAM_ERROR, "余额不能为负");
}
return user;
}
public void transfer(Long fromId, Long toId, BigDecimal amount) {
// 使用连串校验
User fromUser = userRepository.findById(fromId)
.orElseThrow(() -> new BusinessException(ErrorCode.USER_NOT_FOUND));
if (fromUser.getBalance().compareTo(amount) < 0) {
throw new BusinessException(400, "余额不足");
}
// 业务逻辑...
}
}
五、全局异常处理
java
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(BusinessException.class)
public Result<?> handleBusinessException(BusinessException e) {
// 统一返回格式
return Result.error(e.getCode(), e.getMessage());
}
@ExceptionHandler(Exception.class)
public Result<?> handleOtherException(Exception e) {
// 其他异常
log.error("系统异常", e);
return Result.error(500, "系统异常");
}
}
// 统一返回结果
@Data
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.code = 200;
result.message = "成功";
result.data = data;
return result;
}
public static <T> Result<T> error(Integer code, String message) {
Result<T> result = new Result<>();
result.code = code;
result.message = message;
return result;
}
}
六、总结要点
最简写法(记住这个就行):
java
public class BusinessException extends RuntimeException {
private Integer code;
public BusinessException(Integer code, String message) {
super(message);
this.code = code;
}
}
使用三部曲:
-
定义异常类(上面代码)
-
在需要的地方抛出
javaif (条件不满足) { throw new BusinessException(400, "错误信息"); } -
全局处理(返回统一格式)
记住几个常用错误码:
-
400:参数错误 -
401:未登录 -
403:无权限 -
404:不存在 -
500:系统错误