【开发指南】统一数据响应格式

630 阅读2分钟

说明

在前后端分离项目中,为了开发效率,前后端工程师需要争对每一类的接口定义统一的返回结果。经过长时间的反复探索,最终统一将返回数据封装成json进行前后端数据交互。

一般情况下,统一返回数据格式没有固定的格式,只要能描述清楚返回的数据状态以及要返回的具体数据就可以。但是一般会包含响应结果success状态码code返回消息message数据data这几部分内容。

统一数据格式

  1. 一般格式

    {
        "success": Boolean, // 响应结果(true/false)
        "code": Integer, // 状态码(20000/20001/21001/21002...)
        "message": String, // 返回消息 
        "data": HashMap // 数据
    }
    
  2. 没有返回数据

    {
        "success": Boolean, 
        "code": Integer, 
        "message": String, 
        "data": {}
    }
    
  3. 返回数据中有列表

    {
        "success": Boolean, 
        "code": Integer, 
        "message": String, 
        "data": {      
            "items": [ //列表
                {
                    "id": 1,
                    "username": "AydenBryan",
                    "password": "123456"
                },
                ...
            ],
            ...
        }
    }
    
  4. 分页

    {
        "success": Boolean, 
        "code": Integer, 
        "message": String, 
        "data": {
            "total": Integer, // 条目总数
            "rows": [ // 当前页条目
                {
                    "id": 1,
                    "username": "AydenBryan",
                    "password": "123456"
                },
                ...
            ]
        }
    }
    

Spring Cloud实战

  1. 在common服务中创建constant

  2. constant中创建统一结果枚举类

    @Getter
    public enum ResultCodeEnum {
    
        // 所有枚举成员,必须先定义,使用分号结束
        SUCCESS(true, 20000, "成功"),
        UNKNOWN_REASON_ERROR(false, 20001, "未知错误"),
        BAD_SQL_GRAMMAR_ERROR(false, 20002, "sql语法错误"),
        JSON_PARSE_ERROR(false, 20003, "json解析错误"),
        FILE_UPLOAD_ERROR(false, 20004, "文件上传错误"),
        EXCEL_DATA_IMPORT_ERROR(false, 20005, "Excel数据导入错误");
    
        private final Boolean success;
        private final Integer code;
        private final String message;
    
        ResultCodeEnum(Boolean success, Integer code, String message) {
            this.success = success;
            this.code = code;
            this.message = message;
        }
    }
    
  3. 在common服务中创建vo

  4. vo中创建统一数据响应类

    @Data
    public class Result {
    
        private Boolean success;
        private Integer code;
        private String message;
        private Map<String, Object> data;
    
        private Result() {
            this.data = new HashMap<>();
        }
    
        /**
         * 成功
         * @return 统一响应对象
         */
        public static Result ok() {
            Result result = new Result();
            result.setSuccess(ResultCodeEnum.SUCCESS.getSuccess());
            result.setCode(ResultCodeEnum.SUCCESS.getCode());
            result.setMessage(ResultCodeEnum.SUCCESS.getMessage());
            return result;
        }
    
         /**
          * 各种错误
          * @param resultCodeEnum 枚举中定义的错误实体
          * @return 统一响应对象
          */
         public static Result error(ResultCodeEnum resultCodeEnum) {
             Result result = new Result();
             result.setSuccess(resultCodeEnum.getSuccess());
             result.setCode(resultCodeEnum.getCode());
             result.setMessage(resultCodeEnum.getMessage());
             return result;
         }
    
        /**
         * 向data中填充数据
         * @param key 键
         * @param value 值
         * @return 统一响应对象
         */
        public Result data(String key, Object value) {
            this.data.put(key, value);
            return this;
        }
    
        /**
         * 自定义给success赋值
         * @return 统一响应对象
         */
        public Result success(Boolean success) {
            this.setSuccess(success);
            return this;
        }
    
        /**
         * 自定义给code赋值
         * @return 统一响应对象
         */
        public Result code(Integer code) {
            this.setCode(code);
            return this;
        }
    
        /**
         * 自定义给message赋值
         * @return 统一响应对象
         */
        public Result message(String messsage) {
            this.setMessage(messsage);
            return this;
        }
    }
    
  5. 统一Controller中所有API的响应数据格式

     @RestController
     @RequestMapping("/users")
     public class UserController {
    
         @Autowired
         private UserService userService;
    
          // 查询所有用户
         @GetMapping("/")
         public Result listUsers() {
             List<User> users = userService.listUsers();
             if (users != null) {
                 return Result.ok().data("items", users);
             }
             return Result.error(ResultCodeEnum.UNKNOWN_REASON_ERROR);
         }
    
         // 根据id删除用户
         @DeleteMapping("/{id}")
         public Result removeUserById(@PathVariable String id) {
             Boolean result = userService.removeUserById(id);
             if (result == true) {
                 return Result.ok();
             }
             return Result.error(ResultCodeEnum.UNKNOWN_REASON_ERROR);
         }
    
         // 用户分页
         @GetMapping("/pages/{current}/{size}")
         public Result pageUsers(@PathVariable Long current, @PathVariable Long size) {
             Map<String, Object> result = userService.pageUsers(current, size);
             Long total = result.get("total");
             List<User> users = result.get("users");
             if (total != 0 && users != null) {
                 return Result.ok().data("total", total).data("rows", users);
             }
             return Result.error(ResultCodeEnum.UNKNOWN_REASON_ERROR);
         }
     }