简介

这是一个基于Spring Boot 的轻量级工具包,用于统一处理应用程序中的错误码、异常和响应格式。该starter提供了一套完整的异常处理机制,帮助开发者更加规范和高效地管理API响应和错误处理。

功能特点

  • 统一错误码管理:预定义常用错误码,支持自定义扩展
  • 自定义业务异常:提供BusinessException类,支持错误码和自定义错误信息
  • 异常抛出工具类:ThrowUtils工具类简化异常抛出操作
  • 全局异常处理:自动捕获并处理各类异常,转换为统一的响应格式
  • 响应结果封装:统一API响应格式,提供成功和失败响应的快捷方法
  • 参数校验异常处理:自动处理参数校验失败的情况
  • 自动配置:支持Spring Boot自动配置,零配置即可使用

安装方法

在您的Spring Boot项目的pom.xml中添加以下依赖

Spring Boot 2(java8)

      <dependency>
    <groupId>io.github.liyao52033</groupId>
    <artifactId>ErrorCode-spring-boot-starter</artifactId>
    <version>1.2.0</version>
</dependency>
    

Spring Boot 3(java17)

      <dependency>
    <groupId>io.github.liyao52033</groupId>
    <artifactId>liyao-spring-boot3-starter-ErrorCode</artifactId>
    <version>1.2.0</version>
</dependency>
    

基本使用

_1. 自定义错误码

你可以使用预定义的错误码,也可以通过继承或创建新的枚举类来自定义错误码:

      public enum MyErrorCode {
    
    // 使用预定义的错误码
    USER_NOT_FOUND(40400, "用户不存在"),
    USERNAME_ALREADY_EXISTS(44900, "用户名已存在"),
    INVALID_PASSWORD(40000, "密码格式不正确");
    
    private final int code;
    private final String message;
    
    MyErrorCode(int code, String message) {
        this.code = code;
        this.message = message;
    }
    
    public int getCode() {
        return code;
    }
    
    public String getMessage() {
        return message;
    }
}
    

_2. 使用ThrowUtils抛出异常

ThrowUtils提供了多种方法来简化异常抛出

      // 根据条件抛出异常
ThrowUtils.throwIf(user == null, ErrorCode.NOT_FOUND_ERROR, "用户不存在");

// 直接抛出异常
ThrowUtils.throwIf(ErrorCode.PARAMS_ERROR, "参数不能为空");

// 使用自定义错误码
ThrowUtils.throwIf(username == null, MyErrorCode.USER_NOT_FOUND);

// 条件判断后抛出异常
ThrowUtils.throwIf(
    username.length() < 4, 
    new BusinessException(40000, "用户名长度不能小于4")
);
    

_3. 使用ResultUtils封装响应

      @RestController
@RequestMapping("/api/users")
public class UserController {
    
    @GetMapping("/{id}")
    public BaseResponse<UserVO> getUserById(@PathVariable Long id) {
        // 业务逻辑...
        UserVO userVO = userService.getUserById(id);
        // 成功响应
        return ResultUtils.success(userVO);
    }
    
    @PostMapping
    public BaseResponse<Long> createUser(@RequestBody UserCreateRequest request) {
        // 参数校验
        if (request.getUsername() == null) {
            // 失败响应
            return ResultUtils.error(ErrorCode.PARAMS_ERROR, "用户名不能为空");
        }
        // 业务逻辑...
        Long userId = userService.createUser(request);
        return ResultUtils.success(userId);
    }
}
    

_4. 全局异常处理

该starter已经内置了全局异常处理器,会自动捕获并处理以下类型的异常:

  • BusinessException:业务异常,返回对应的错误码和错误信息
  • RuntimeException:运行时异常,返回系统错误码
  • MethodArgumentNotValidException:参数校验异常,返回参数错误码和具体的校验错误信息

你无需额外配置,全局异常处理器会自动生效。

高级用法

_1. 自定义全局异常处理器

如果你需要处理更多类型的异常,可以创建自己的全局异常处理器:

      @RestControllerAdvice
@Slf4j
public class MyGlobalExceptionHandler extends GlobalExceptionHandler {
    
    // 处理自定义异常
    @ExceptionHandler(MyCustomException.class)
    public BaseResponse<?> handleMyCustomException(MyCustomException e) {
        log.error("MyCustomException", e);
        return ResultUtils.error(e.getCode(), e.getMessage());
    }
    
    // 覆盖默认的RuntimeException处理
    @Override
    public BaseResponse<?> runtimeExceptionHandler(RuntimeException e) {
        log.error("RuntimeException", e);
        // 自定义处理逻辑
        return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "系统繁忙,请稍后再试");
    }
}
    

_2. 扩展BaseResponse

如果需要在响应中添加更多字段,可以扩展BaseResponse类:

      @Data
@EqualsAndHashCode(callSuper = true)
public class MyResponse<T> extends BaseResponse<T> {
    
    private long timestamp;
    private String traceId;
    
    public MyResponse(int code, T data, String message) {
        super(code, data, null, null, message);
        this.timestamp = System.currentTimeMillis();
        this.traceId = MDC.get("traceId");
    }
    
    // 其他构造方法...
}
    

最佳实践

  1. 统一错误码管理:在一个地方定义所有错误码,避免重复和冲突
  2. 使用ThrowUtils:使用ThrowUtils简化异常抛出,提高代码可读性
  3. 参数校验:结合Spring Validation进行参数校验,全局异常处理器会自动处理校验异常
  4. 日志记录:异常发生时会自动记录日志,便于问题排查
  5. 前端友好:统一的响应格式使前端处理更加简单

声明

作者: liyao

版权:本博客所有文章除特别声明外,均采用CCBY-NC-SA4.O许可协议。转载请注明!

最后更新于 2025-09-30 20:31 history