后端接口通用返回格式与异常处理实现

前言

目前大部分系统都是前后端分离架构,后端提供接口并返回 JSON 数据,前端接收数据后进行处理展示。为了提高前后端协作效率,后端接口返回值采用固定格式十分必要。

后端接口返回值通用格式

通用返回值通常包含 4 个核心字段,代码定义如下:

java 复制代码
public class Result<T> {
    /**
     * 请求是否处理成功
     */
    private boolean success;
    /**
     * 数据,泛型类型,存储后端返回给前端的业务数据
     */
    private T data;
    /**
     * 提示消息,当success为false时给用户的提示信息
     */
    private String msg;
    /**
     * 错误编码,提供详细错误标识,便于前端根据不同编码做差异化处理
     */
    private String code;
}

接口示例

java 复制代码
@RestController
public class TestController {

    @GetMapping("/hello")
    public Result<String> hello() {
        return ResultUtils.success("hello");
    }
    
}

前端接收结果

java 复制代码
{
  "success": true,
  "data": "hello",
  "msg": null,
  "code": null
}

异常情况处理

后端接口通常包含校验逻辑,如登录接口需要验证用户名和密码。当验证不通过时,应返回标准化的错误信息:

java 复制代码
{

"success": false,

"data": null,

"msg": "用户名或密码错误",

"code": "1001"

}

实现方式:后端校验不通过时抛出业务异常,通过全局异常处理器统一处理并返回通用格式结果。

具体实现步骤

1. 自定义业务异常类

java 复制代码
public class BusinessException extends RuntimeException {
    private String code;

    /**
     * @param code    错误编码
     * @param message 错误提示信息
     */
    public BusinessException(String code, String message) {
        super(message);
        this.code = code;
    }

    public BusinessException(String code, String message, Throwable cause) {
        super(message, cause);
        this.code = code;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }
}

2. 接口中抛出业务异常

以登录接口为例,当用户名验证不通过时抛出异常:

java 复制代码
@GetMapping("/login")
public Result<String> login(String name) {
    if (!"chen".equals(name)) {
        throw new BusinessException("1001", "用户名错误");
    } else {
        return ResultUtils.success("登录成功");
    }
}

3. 全局异常处理 BusinessException

使用 SpringBoot 的全局异常处理器处理业务异常,通过@RestControllerAdvice和@ExceptionHandler注解实现:

java 复制代码
@RestControllerAdvice
public class GlobalExceptionHandler {
    private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
     * 处理业务异常
     *
     * @param e       业务异常对象
     * @param request 请求对象
     * @return 通用返回结果
     */
    @ExceptionHandler(BusinessException.class)
    public Result handleBusinessException(BusinessException e, HttpServletRequest request) {
        logger.info("请求:{},发生异常:{}", request.getRequestURL(), e.getMessage(), e);
        return ResultUtils.error(e.getCode(), e.getMessage());
    }

}

4. 验证效果

java 复制代码
{
  "success": true,
  "data": "登录成功",
  "msg": null,
  "code": null
}
java 复制代码
{
  "success": false,
  "data": null,
  "msg": "用户名错误",
  "code": "1001"
}

案例:SpringBoot 参数校验异常处理

SpringBoot 提供参数自动校验功能,以下是具体实现:

1. 用户注册接口

java 复制代码
@PostMapping("/userRegister")

public Result<Void> userRegister(@Validated @RequestBody UserRegisterRequest req) {

return ResultUtils.success();

}

2. 参数校验异常处理

当参数校验不通过时,SpringBoot 会抛出BindException异常,在全局异常处理器中添加对应处理方法:

java 复制代码
@ExceptionHandler(BindException.class)

public Result handleBindException(BindException e, HttpServletRequest request) {

logger.info("请求:{},发生异常:{}", request.getRequestURL(), e.getMessage(), e);

String message = e.getAllErrors().get(0).getDefaultMessage();

return ResultUtils.error(message);

}

全局其他异常处理

添加兜底异常处理方法,处理所有未被专门捕获的异常:

java 复制代码
/**

* 处理其他未明确捕获的异常

*

* @param e 异常对象

* @param request 请求对象

* @return 通用返回结果

*/

@ExceptionHandler(Exception.class)

public Result handleException(Exception e, HttpServletRequest request) {

logger.info("请求:{},发生异常:{}", request.getRequestURL(), e.getMessage(), e);

return ResultUtils.error(ErrorCode.SERVER_ERROR, "系统异常,请稍后重试");

}

提供的工具类

ResultUtils

java 复制代码
public class ResultUtils {
    public static final String SUCCESS = "1";
    public static final String ERROR = "0";

    public static <T> Result<T> ok()
    {
        return result(SUCCESS, null, null);
    }

    public static <T> Result<T> ok(T data)
    {
        return result(SUCCESS, data, null);
    }

    public static <T> Result<T> error(String msg)
    {
        return result(ERROR, null, msg);
    }

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

BusinessExceptionUtils

java 复制代码
public class BusinessExceptionUtils
{
    /**
     * 创建 BusinessException
     */
    public static BusinessException businessException(String code, String msg)
    {
        return new BusinessException(code, msg);
    }
}

ErrorCode

java 复制代码
public class ErrorCode
{
    public static final String SERVER_ERROR = "500";
}
相关推荐
大江东去浪淘尽千古风流人物8 天前
【HexVIO】DSP卸载双目惯性VIO:Hexagon向量化前端与单帧融合调度深度解析
前端·状态模式·slam·dsp·vio·hexagon·移动端加速
吃一碗粉只付一碗钱9 天前
12-给SPA友好的401和403响应
c#·状态模式
sunlifenger9 天前
嵌入式部署,解锁张家港智慧灯杆的“极简组网”密码
科技·状态模式
上火的金鱼妹10 天前
关于多进程sse连接通知的实战
javascript·状态模式·sse
阿俊-全栈开发10 天前
LikeShop 小程序商城首页可配置弹窗的设计与实现(Java + uni-app)
小程序·状态模式·likeshop·likeshop开源商城
lingyubb11 天前
配音工具怎么选?从 TTS 合成链路看 6 个可量化参数
状态模式
平头哥技术团队12 天前
从预订问到退房:一间山野民宿的数字人「旅程地图」——Theme07_Homestay.vue 端到端拆解
状态模式·数字人
未来之窗软件服务13 天前
web网络请求竞态问题与取消方案-东方仙盟
前端·状态模式·仙盟创梦ide·东方仙盟·网络取消
一级新生14 天前
多智能体协作:常用协作模式详解
人工智能·状态模式·agent·多智能体·智能体