---
date: 2025-04-15 12:00:07
title: 管理API响应和错误处理
permalink: /pages/748a67
author:
  name: 华总
  link: https://xiaoying.org.cn
tags:
  - Spring Boot
categories:
  - 后端
  - 功能扩展

---

## 简介

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

## 功能特点

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

## 安装方法

::: tip 

依赖可能非最新版本，请前往maven获取最新版本

[Spring Boot 2](https://central.sonatype.com/artifact/io.github.liyao52033/ErrorCode-spring-boot-starter)地址

[Spring Boot 3](https://central.sonatype.com/artifact/io.github.liyao52033/liyao-spring-boot3-starter-ErrorCode)地址

:::

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

Spring Boot 2(java8)

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

Spring Boot 3(java17)

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

## 基本使用

### 1. 自定义错误码

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

```java
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提供了多种方法来简化异常抛出

```java
// 根据条件抛出异常
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封装响应

```java
@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. 自定义全局异常处理器

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

```java
@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类：

```java
@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. **前端友好**：统一的响应格式使前端处理更加简单
