Spring Boot 统一封装返回结果与枚举错误码(完整解决方案)

Spring Boot 统一封装返回结果与枚举错误码(完整解决方案)

一、前言

在 Spring Boot 项目开发中,如果不统一接口返回格式,前端会对接多种返回结构,增加调试和维护成本。同时错误码分散在代码中、硬编码提示语,会导致维护困难、错误信息不统一、不利于国际化和接口规范化。

本文实现一套企业级通用方案

  • 统一接口返回结果实体类

  • 统一枚举错误码(系统码 + 业务码)

  • 自定义业务异常

  • 全局异常统一处理

  • 完整测试接口演示

统一返回格式标准:

{
  "code": 200,
  "msg": "操作成功",
  "data": {}
}

二、核心结构说明

项目核心 4 个核心类:

  1. Result:统一返回结果封装类

  2. ResultEnum:全局状态码、错误码枚举

  3. BusinessException:自定义业务异常

  4. GlobalExceptionHandler:全局异常处理器

三、代码实现

3.1 统一返回结果实体类 Result

所有接口统一返回该实体,提供成功、失败静态方法,简化代码。

import lombok.Data;

/**
 * 统一接口返回结果封装
 */
@Data
public class Result<T> {

    /**
     * 响应码
     */
    private Integer code;

    /**
     * 响应信息
     */
    private String msg;

    /**
     * 响应数据
     */
    private T data;

    // ==================== 成功响应 ====================
    public static <T> Result<T> success() {
        return success(null);
    }

    public static <T> Result<T> success(T data) {
        Result<T> result = new Result<>();
        result.setCode(ResultEnum.SUCCESS.getCode());
        result.setMsg(ResultEnum.SUCCESS.getMsg());
        result.setData(data);
        return result;
    }

    // ==================== 失败响应 ====================
    public static <T> Result<T> fail(ResultEnum resultEnum) {
        Result<T> result = new Result<>();
        result.setCode(resultEnum.getCode());
        result.setMsg(resultEnum.getMsg());
        return result;
    }

    public static <T> Result<T> fail(Integer code, String msg) {
        Result<T> result = new Result<>();
        result.setCode(code);
        result.setMsg(msg);
        return result;
    }
}

3.2 全局错误码枚举 ResultEnum

统一管理所有状态码,分为:系统通用码、业务自定义码,可根据业务扩展。

/**
 * 全局统一返回码枚举
 * 约定:2xx 成功,4xx 客户端错误,5xx 服务端错误,10xx 业务自定义错误
 */
public enum ResultEnum {

    // 成功
    SUCCESS(200, "操作成功"),

    // 客户端错误
    PARAM_ERROR(400, "参数校验失败"),
    UNAUTHORIZED(401, "未登录或token失效"),
    FORBIDDEN(403, "权限不足,禁止访问"),
    NOT_FOUND(404, "请求资源不存在"),

    // 服务端错误
    SERVER_ERROR(500, "服务器内部异常"),

    // 业务自定义错误码(根据业务自行扩展)
    USER_NOT_EXIST(1001, "用户不存在"),
    USER_PASSWORD_ERROR(1002, "密码错误"),
    USER_ACCOUNT_LOCK(1003, "账号已被锁定"),
    DATA_IS_EMPTY(1004, "数据不存在"),
    REPEAT_SUBMIT(1005, "请勿重复提交");

    private final Integer code;
    private final String msg;

    ResultEnum(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public Integer getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }
}

3.3 自定义业务异常 BusinessException

用于业务代码中主动抛出异常,配合全局异常处理器统一返回。

/**
 * 自定义业务异常
 */
public class BusinessException extends RuntimeException {

    private Integer code;
    private String msg;

    public BusinessException(ResultEnum resultEnum) {
        super(resultEnum.getMsg());
        this.code = resultEnum.getCode();
        this.msg = resultEnum.getMsg();
    }

    public BusinessException(Integer code, String msg) {
        super(msg);
        this.code = code;
        this.msg = msg;
    }

    public Integer getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }
}

3.4 全局异常处理器 GlobalExceptionHandler

拦截系统异常、业务异常、参数异常,统一封装为 Result 返回,保证接口格式统一。

import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * 全局统一异常处理
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 自定义业务异常
     */
    @ExceptionHandler(BusinessException.class)
    public Result<Void> businessExceptionHandler(BusinessException e) {
        return Result.fail(e.getCode(), e.getMsg());
    }

    /**
     * 参数校验异常
     */
    @ExceptionHandler(IllegalArgumentException.class)
    public Result<Void> paramExceptionHandler(IllegalArgumentException e) {
        return Result.fail(ResultEnum.PARAM_ERROR.getCode(), e.getMessage());
    }

    /**
     * 系统全局异常
     */
    @ExceptionHandler(Exception.class)
    public Result<Void> exceptionHandler(Exception e) {
        e.printStackTrace();
        return Result.fail(ResultEnum.SERVER_ERROR);
    }
}

四、测试接口使用示例

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/test")
public class TestController {

    /**
     * 正常返回示例
     */
    @GetMapping("/success")
    public Result<String> success() {
        return Result.success("请求成功,Hello SpringBoot");
    }

    /**
     * 业务异常抛出示例
     */
    @GetMapping("/user/{id}")
    public Result<Void> getUser(@PathVariable Integer id) {
        // 模拟业务判断
        if (id == null || id <= 0) {
            throw new BusinessException(ResultEnum.PARAM_ERROR);
        }
        if (id == 999) {
            throw new BusinessException(ResultEnum.USER_NOT_EXIST);
        }
        return Result.success();
    }
}

五、返回效果演示

5.1 成功响应

{
  "code": 200,
  "msg": "操作成功",
  "data": "请求成功,Hello SpringBoot"
}

5.2 业务异常响应

{
  "code": 1001,
  "msg": "用户不存在",
  "data": null
}

5.3 参数异常响应

{
  "code": 400,
  "msg": "参数校验失败",
  "data": null
}

六、使用规范与扩展技巧

6.1 编码规范

  • 所有接口必须返回 Result 泛型对象,禁止直接返回实体、字符串、布尔值;

  • 业务校验不通过,优先抛出 BusinessException,不手动 return 失败结果;

  • 所有错误描述统一维护在 ResultEnum,禁止代码硬编码错误提示文字。

6.2 错误码设计规范

  • 200:统一成功码

  • 4xx:客户端错误(参数、权限、未登录)

  • 5xx:服务端未知异常

  • 10xx / 11xx...:自定义业务错误码,可按模块分段(用户、订单、支付等)

6.3 可扩展方向

  • 增加国际化 i18n:错误信息从配置文件读取,支持多语言;

  • 增加日志打印:全局异常中记录请求参数、异常堆栈,方便排查问题;

  • 增加分页结果封装:基于 Result 扩展 PageResult 分页返回实体;

  • 统一 API 文档注解,配合 Swagger/OpenAPI 生成标准响应示例。

七、总结

通过这套统一返回结果 + 枚举错误码方案,彻底解决了 Spring Boot 项目接口返回格式混乱、错误码零散、异常处理不统一的问题。代码低侵入、通用性强、符合企业级开发规范,可直接引入任何 Spring Boot 项目使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码客日记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值