zoukankan      html  css  js  c++  java
  • 如何优雅的处理Restful

    最近公司搭建的项目,前端反映后端返回格式不统一的问题,因此引发小编的思考,如何能够优雅的处理返回值格式呢?在度娘中仔细研读了一番,决定总结一下,于是乎此文便诞生了。

    一、背景

    首先,大家都会思考为什么要做统一格式处理呢?

    现阶段的开发模式多以前后端分离形式存在,前后端开发人员需要通过大量 API 来进行数据交互,如果在交互过程中前后端人员经常遭遇如下问题:

    • 前端人员不能快速理解接口字段含义及接口字段变化

    • 后端人员想复用某些接口,但是不能快速从接口 URL 的定义中明确该接口的含义,需要进一步读代码确认

    • URL中的英文单词使用五花八门,搜索某个接口不知道具体的关键字

    • 请求方法动词如 POST GET 随意使用

    • 完成当前业务接口对接,前端人员经常会询问下一步业务流程的接口定义在哪里,对接形式是什么样的

    以上只是前后端人员通过接口交互的一小部分问题,这些问题就好比"牙痛",不致命,但是在整个软件开发的生命周期内,天天"牙痛”是很要命的, 需要解决上述的问题,需要前后端人员都能认识与了解接口设计规范的重要性。因此,如何让前端小伙伴可以处理标准的 response JSON 数据结构都至关重要。

    通过上面一个问题把大家带入正题,下面我们统一定义一下格式。

    二、格式定义

    2.1结果格式定义

    每一次 RESTful 请求都应该包含以下几个信息:

    名称

    描述

    success

    标识请求成功与否,false、true

    code

    状态码,标识错误类型

    message

    提示信息

    data

    返回数据

    2.2结果枚举类定义

    /**
     * @Author:qxy
     * @Date:2020/4/7 13:07
     */
    public enum ResultCodeEnum {
        /*** 通用部分 100 - 599***/
        // 成功请求
        SUCCESS(200, "successful"),
        // 重定向
        REDIRECT(301, "redirect"),
        // 资源未找到
        NOT_FOUND(404, "not found"),
        // 服务器错误
        SERVER_ERROR(500,"server error"),
    
        BUSINESS_EXCEPTION(4000, "business exception"),
        ;
    
        private Integer code;
    
        private String message;
    
        //省略get/set方法
    }

    为了日常开发中规范状态码,这里着重参考一下Http定义的规范:

    常见的HTTP状态码如:
    200 - 请求成功;
    301 - 资源(网页等)被永久转移到其它URL;
    404 - 请求的资源(网页等)不存在;
    500 - 内部服务器错误。
    message:错误信息
    在发生错误时,如何友好的进行提示?
    1.根据code 给予对应的错误码定位;
    2.把错误描述记录到message中,便于接口调用者更详细的了解错误。

    状态码类型

    code区间

    类型

    含义

    1

    100-199

    信息

    服务器接收到请求,需要请求者继续执行操作

    2

    200-299

    成功

    请求被成功接收并处理

    3

    300-399

    重定向

    需要进一步的操作以完成请求

    4

    400-499

    客户端错误

    请求包含语法错误或无法完成请求

    5

    500-599

    服务端错误

    服务器在处理的时候发生错误

    2.3统一结果类

    /**
     * @Author:qxy
     * @Date:2020/4/7 13:11
     */
    public class HttpResult<T> implements Serializable {
    
        private Boolean success;
    
        private Integer code;
    
        private String message;
    
        private T data;
        //省略get/set
    
        /**
         * 无参构造
         */
        public HttpResult() {
            this.success = true;
            this.code = ResultCodeEnum.SUCCESS.getCode();
            this.message = ResultCodeEnum.SUCCESS.getMessage();
        }
    
        /**
         * 有参构造:返回成功
         * @param object
         */
        public HttpResult(T object) {
            this.success = true;
            this.code = ResultCodeEnum.SUCCESS.getCode();
            this.message = ResultCodeEnum.SUCCESS.getMessage();
            this.data = object;
        }
    
        /**
         * 有参构造:返回失败
         * @param resultCode
         */
        public HttpResult(ResultCodeEnum resultCode) {
            this.success = false;
            this.code = resultCode.getCode();
            this.message = resultCode.getMessage();
        }
        
    }

    2.4定义业务场景返回类

    /**
     * @Author:qxy
     * @Date:2020/4/7 13:57
     */
    public class ResultResponse {
        /**
         * 通用返回成功(没有返回结果)
         * @param
         * @return
         */
        public static HttpResult success(){
            return new HttpResult();
        }
    
        /**
         * 返回成功(有返回结果)
         * @param data
         * @return
         */
        public static<T> HttpResult success(T data){
            return new HttpResult<T>(data);
        }
    
        /**
         * 通用返回失败
         * @param resultCode
         * @param <T>
         * @return
         */
        public static<T> HttpResult<T> failure(ResultCodeEnum resultCode){
            return new HttpResult<T>(resultCode);
        }
    
        /**
         * 捕获异常类型设置状态和提示信息
         * @param code
         * @param message
         * @param <T>
         * @return
         */
        public static<T> HttpResult<T> failure(Integer code, String message) {
            ResultCodeEnum resultCodeEnum = ResultCodeEnum.BUSINESS_EXCEPTION;
            resultCodeEnum.setCode(code);
            resultCodeEnum.setMessage(message);
            return failure(resultCodeEnum);
        }
    }

    三、测试

    /**
     * @Author:qxy
     * @Date:2020/4/7 9:45
     */
    @RestController
    public class StudentController {
    
        @Autowired
        private StudentService studentService;
    
        @GetMapping("/getStudentList")
        public HttpResult getStudentList(){
            return ResultResponse.success(studentService.getStudentList());
        }
    }

    详细代码请移步github下载:https://github.com/stream-source/stream-source/tree/master/informal-essay/src/main/java/com/qxy/response

    参考资料:风尘博客

  • 相关阅读:
    关于报错”已有打开的于此Command相关联的DataReader,必须首先将它关闭。“的问题
    Dockerjenkins环境搭建跟配置
    Python+selenium 【第十章】封装config类,读取配置文件,封装驱动类,适配windows/mac
    —— “欢迎来到我的小屋”
    Python+selenium 【第九章】封装excel类,封装test_data类 读取测试元素信息
    Linux搭建docker
    Python+selenium 【第十二章】封装日志类优化其他方法并添加日志(异常处理)
    【selenium】Python自动化面试题
    Dockerjenkins容器安装python并配置环境变量
    【优化框架】新增期望结果,断言为mysql情况下动态化参数替换
  • 原文地址:https://www.cnblogs.com/wx_blog/p/12656316.html
Copyright © 2011-2022 走看看