微服务中通过自定义businessexception异常类、errorcode枚举和@controlleradvice全局处理器实现错误码与信息的统一封装,业务层仅抛异常,框架自动转换为标准响应体。

在微服务中,自定义异常统一封装错误码和错误信息,核心是让异常本身携带结构化错误数据,并通过全局异常处理器(@ControllerAdvice)转换为标准响应体(如 { "code": 40001, "message": "用户名已存在", "data": null }),避免业务代码到处写重复的返回逻辑。
定义统一异常基类:含错误码、消息、可选上下文
建议继承 RuntimeException(非检查异常,调用方无需强制 try-catch),并提供多构造函数支持灵活传参:
public class BusinessException extends RuntimeException {
private final int code;
private final String message;
// 最简构造:只传错误码(从枚举获取默认消息)
public BusinessException(ErrorCode errorCode) {
super(errorCode.getMessage());
this.code = errorCode.getCode();
this.message = errorCode.getMessage();
}
// 支持动态填充消息占位符(如"用户 {0} 不存在" → "用户 admin 不存在")
public BusinessException(ErrorCode errorCode, Object... args) {
super(MessageFormat.format(errorCode.getMessage(), args));
this.code = errorCode.getCode();
this.message = MessageFormat.format(errorCode.getMessage(), args);
}
// 支持手动指定消息(慎用,破坏一致性)
public BusinessException(int code, String message) {
super(message);
this.code = code;
this.message = message;
}
// getter 省略...
}
定义错误码枚举:集中管理,语义清晰,支持国际化扩展
把所有错误码收拢到一个枚举里,每个枚举项包含唯一码值、默认提示、HTTP 状态建议(可选)。例如:
public enum ErrorCode {
SUCCESS(200, "操作成功"),
USER_NOT_FOUND(40401, "用户不存在"),
USERNAME_DUPLICATED(40001, "用户名已存在"),
INVALID_PARAM(40000, "参数不合法:{0}"),
SYSTEM_ERROR(50000, "系统繁忙,请稍后重试");
private final int code;
private final String message;
ErrorCode(int code, String message) {
this.code = code;
this.message = message;
}
// getter 省略...
}
这样抛异常就非常干净:throw new BusinessException(ErrorCode.USERNAME_DUPLICATED, "test_user");
全局异常处理器:统一封装成标准响应格式
用 @ControllerAdvice 拦截所有控制器异常,区分不同异常类型,返回统一 JSON 结构:
@ControllerAdvice
public class GlobalExceptionHandler {
@ResponseBody
@ExceptionHandler(BusinessException.class)
public Result> handleBusinessException(BusinessException e) {
return Result.fail(e.getCode(), e.getMessage());
}
@ResponseBody
@ExceptionHandler(MethodArgumentNotValidException.class)
public Result> handleValidationException(MethodArgumentNotValidException e) {
String defaultMessage = e.getBindingResult().getFieldError().getDefaultMessage();
return Result.fail(40000, "参数校验失败:" + defaultMessage);
}
@ResponseBody
@ExceptionHandler(Exception.class)
public Result> handleUnexpectedException(Exception e) {
log.error("未预期异常", e);
return Result.fail(50000, "系统异常,请联系管理员");
}
}
其中 Result<t></t> 是你项目约定的通用响应体,含 code、message、data 字段。
业务层直接抛异常,不手动构造 Response
Controller 层保持纯粹,只关注业务流程,异常由框架自动捕获处理:
- ✅ 正确写法:
if (userRepo.existsByUsername(username)) { throw new BusinessException(ErrorCode.USERNAME_DUPLICATED, username); } - ❌ 错误写法:
return Result.fail(40001, "用户名已存在");—— 打破异常语义,且无法被全局处理器统一日志/监控
这种设计让错误处理与业务逻辑解耦,也便于后续接入熔断、告警、链路追踪等能力。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











