SpringBoot实战:SpringBoot 统一接口响应的正确格式

引言

目前在绝大多数的系统开发基本都是前后端分离的开发模式,为了加快前后端接口的对接响应速度,有一套完整且实用的接口标准格式是非常重要的,不仅能提升开发效率,还可以让代码看起来更加简洁,更好维护。


今天这篇文章让我们来了解下如何在 SpringBoot 前后端开发工程中怎么来实现统一的接口返回数据格式。


一、定义标准的数据返回格式

常见的一种数据返回格式是封装一个工具类,在类中定义需要返回到前端的字段信息,比如响应状态码,数据结果集,结果描述等,然后再接口中返回给客户端。

示例代码:

定义返回对象;

public class ResultMsg<T> {

    /**状态码**/
    private int code;

    /**结果描述**/
    private String message;

    /**结果集**/
    private T data;

    /**时间戳**/
    private long timestamp;

    // set、get方法等...

    public ResultMsg() {
        timestamp = System.currentTimeMillis();
    }

    public static <T> ResultMsg<T> success() {
        return success(null);
    }

    public static <T> ResultMsg<T> success(T data) {
        ResultMsg<T> resultMsg = new ResultMsg<>();
        resultMsg.setCode(ReturnCode.RC200.getCode());
        resultMsg.setMessage(ReturnCode.RC200.getMessage());
        resultMsg.setData(data);
        return resultMsg;
    }

    public static <T> ResultMsg<T> fail(String message) {
        return fail(ReturnCode.RC500.getCode(), message);
    }

    public static <T> ResultMsg<T> fail(ReturnCode returnCode) {
        return fail(returnCode.getCode(), returnCode.getMessage());
    }

    public static <T> ResultMsg<T> fail(int code, String message) {
        ResultMsg<T> resultMsg = new ResultMsg<>();
        resultMsg.setCode(code);
        resultMsg.setMessage(message);
        return resultMsg;
    }
}

在这个类中,<T>表示一个类型参数,意味着你可以创建ResultMsg类的实例来存储任何类型的数据。code字段(属性)用于存储状态码,message字段用于存储结果描述,data字段用于存储结果集,类型为Ttimestamp字段用于存储生成结果消息的时间戳。

定义状态码:

public enum ReturnCode {

    /**操作成功**/
    RC200(200,"请求成功"),

    /**access_denied**/
    RC403(403,"无访问权限,请联系管理员授予权限"),

    /**服务异常**/
    RC500(500,"系统异常,请稍后重试");

    /**自定义状态码**/
    private final int code;

    /**自定义描述**/
    private final String message;

    ReturnCode(int code, String message){
        this.code = code;
        this.message = message;
    }

    public int getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }
}

ReturnCode 是一个枚举类,它代表了不同的返回码。每个返回码都有一个与之关联的整数字段 code 和一个消息字段 message。这些字段用于描述操作的结果,其中 code 是一个状态码,通常用于提供有关操作结果的额外信息。

下面是对代码的详细解释:

  • RC200(200,”请求成功”):这是一个代表请求成功的返回码。状态码 200 通常在 HTTP 协议中表示成功,这里的消息是 “请求成功”,表示请求已被成功处理。

  • RC403(403,”无访问权限,请联系管理员授予权限”):这是一个代表访问被拒绝的返回码。状态码 403 通常在 HTTP 协议中表示没有权限访问资源,这里的消息提供了额外的信息,即用户没有访问权限,并建议他们联系管理员授予权限。

  • RC500(500,”系统异常,请稍后重试”):这是一个代表系统异常的返回码。状态码 500 通常在 HTTP 协议中表示服务器内部错误,这里的消息表明系统出现异常,建议用户稍后重试,表示服务器遇到了错误或异常,导致无法完成请求。

  • private final int code; 和 private final String message;:这是两个私有的字段,分别存储返回码的数字值和消息字符串。final 关键字确保它们一旦被初始化就不能被修改。

  • ReturnCode(int code, String message){ this.code = code; this.message = message;}:这是ReturnCode 枚举类的构造函数。它接受一个int类型的code和一个String类型的message作为参数,并将它们分配给相应的字段。

  • public int getCode() {…} 和 public String getMessage() {…}:这两个方法是获取codemessage字段值的访问器方法。它们允许外部代码获取枚举实例的状态码和消息。


统一的返回格式:

@RestController
public class UserController {
    
    @Autowired
    private UserService userService;

    @RequestMapping(value = "/queryUser")
    public ResultMsg query(@RequestParam("userId") Long userId){
        try {
            // 业务代码...
            User user = userService.queryId(userId);
            return ResultMsg.success(user);
        } catch (Exception e){
            return ResultMsg.fail(e.getMessage());
        }
    }
}

当请求接口时返回的数据格式:

{
    "code": 200,
    "message": "请求成功",
    "data": {
        "userId": 1,
        "userName": "张三"
    },
    "timestamp": 1716540843798
}

注:这种是一种比较常见的方式,但缺点就是重复编程很多,如果写几百个接口,代码会非常臃肿。


二、高级的封装实现方式

SpringBoot 框架中,其实有很多方便开发者调用的实用工具,例如 ResponseBodyAdvice, 在开发过程中我们可以直接利用它来实现统一的数据格式封装。ResponseBodyAdvice 可以在 Controller 层中对标注有 @ResponseBody 注解的方法进行拦截,开发过程中可以利用这个特性来封装返回数据格式等操作。

ResponseBodyAdvice的实用

/**
 * 对controller 层中 ResponseBody 注解方法,进行增强拦截
 */

@ControllerAdvice
public class CustomerResponseAdvice implements ResponseBodyAdvice<Object> {

    /**
     * 是否开启支持功能
     */

    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return true;
    }

    /**
     * 如果开启,就会对返回结果进行处理
     */

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        return ResultMsg.success(body);
    }
}

controller层无需返回ResultMsg对象类型,直接改成对应的业务对象即可

@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping(value = "/queryUser")
    public User query(@RequestParam("userId") Long userId){
        // 业务代码...
        User user = userService.queryId(userId);
        return user;
    }
}



原文始发于微信公众号(Java技术前沿):SpringBoot实战:SpringBoot 统一接口响应的正确格式

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/299720.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!