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

前言

目前大部分系统都是前后端分离架构,后端提供接口并返回 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";
}
相关推荐
前端不太难6 小时前
没有文档模型,HarmonyOS PC 应用会发生什么?
华为·状态模式·harmonyos
GatiArt雷8 小时前
Libvio.link网站反爬机制深度剖析与合规爬虫策略研究
状态模式
Go_Zezhou9 小时前
render快速部署网站和常见问题解决
运维·服务器·开发语言·python·github·状态模式
共享家952717 小时前
搭建 AI 聊天机器人:”我的人生我做主“
前端·javascript·css·python·pycharm·html·状态模式
We1ky1 天前
从零到一:我的javascript记忆翻转卡牌游戏诞生记
状态模式
Elieal1 天前
Spring MVC 全局异常处理实战
spring·mvc·状态模式
Elieal1 天前
统一 JSON 格式,JacksonObjectMapper 定制 Spring Boot JSON 转换规则
spring boot·json·状态模式
前端不太难1 天前
HarmonyOS PC 应用,先做文档模型
华为·状态模式·harmonyos
前端不太难1 天前
HarmonyOS 走向 PC,应用模型正在重构
重构·状态模式·harmonyos
进击的小头2 天前
行为型模式:状态模式——嵌入式状态管理的优雅解决方案
c语言·状态模式