• Spring Boot接口设计规范


    接口参数处理及统一结果响应

    1、接口参数处理

    1、普通参数接收

    这种参数接收方式是比较常见的,由于是GET请求方式,所以在传参时直接在路径后拼接参数和参数值即可。

    例如localhost:8080/api/product/list?key1=value1&key2=value2

    /**
      * 商品列表 - 普通参数接收
      * @return 统一返回对象
      */
     @RequestMapping(value = "/product/list",method = RequestMethod.GET)
     public Result list(
             @RequestParam(required = false) String goodsStatus,
             @RequestParam(required = false) String goodName,
             @RequestParam(required = false) Integer pageNum,
             @RequestParam(required = false) Integer pageSize){
        // 业务逻辑略....
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2、路径参数接收

    在开发过程中会出现部分接口设计时采用将参数拼入路径中的方式,当只需要一个参数时,可以考虑路径参数接收这种接口设计方式。这种请求方式与普通参数接收方式没有很大的区别,个人习惯。。。

    例如:像根据订单号查询,这个时候可以将接口设计成/product/1024,在接口方法的参数列表中使用@PathVariable注解对订单号进行接收。

    /**
      * 根据商品id获取商品详情
      * @return 统一返回对象
      */
     @RequestMapping(value = "/product/{id}",method = RequestMethod.GET)
     public Result goods(@PathVariable("id") Integer productId){
        // 业务逻辑略....
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3、对象参数接收

    在进行接口开发的过程中,项目中的POST或者PUT方法类型的接口,基本上都是以对象形式来接收参数的。

    例如在登录接口中,前端在请求体中传递JSON格式的请求参数,后端使用@RequestBody注解对前端传递过来的JSON数据进行接收,并将参数转换成对应的实体类。

    @RequestMapping(value = "/admin/login", method = RequestMethod.POST)
        public Result<String> login( 
            @RequestBody @Valid AdminLoginParam adminLoginParam){
         // 业务逻辑略....
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    AdminLoginParam

    @Data
    public class AdminLoginParam implements Serializable {
    
        @NotEmpty(message = "登录名不能为空")
        private String userName;
    
        @NotEmpty(message = "密码不能为空")
        private String password;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    这样当前端通过调用/admin/login接口,并传递如下json数据给后端,后端就会接收并处理登录流程了。

    {
        "username" : "panpan",
        "password" : "123123"
    }
    
    • 1
    • 2
    • 3
    • 4

    为了统一数据格式,前端传递数据的过程中,需要统一在请求头中将Content-Type设置为application/json

    4、复杂对象接收

    在开发过程中避免不了会出现一些复杂的对象,这些复杂对象往往都是一个对象中包含另外一个实体对象,或者包含一组对象(List params)

    这种复杂对象接收方式与对象参数接收的方式一样,前端在传递的时候只需要在json串中嵌套一层json对象。后端接收参数时封装一个嵌套对象即可

     @PostMapping("/saveOrder")
     public Result<String> saveOrder(
       @Parameter(description = "订单参数") @RequestBody SaveOrderParam saveOrderParam){
       // 业务逻辑略....
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    SaveOrderParam

    @Data
    public class SaveOrderParam implements Serializable {
    
        // 订单项id数组
        private Long[] cartItemIds;
    
        // 地址id
        private Long addressId;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2、统一结果响应

    为了保证所有接口响应数据格式的统一,这样可以大大减少接口响应的工作量,方便前端同学使用接口。

    /**
     * 统一返回对象
     *
     * @author supanpan
     * @create_date 2023-11-19 11:03
     */
    public class Result<T> implements Serializable {
        private static final long serialVersionUID = 1L;
    
        //业务码,比如成功、失败、权限不足等 code,可自行定义
        private int resultCode;
        //返回信息,后端在进行业务处理后返回给前端一个提示信息,可自行定义
        private String message;
        //数据结果,泛型,可以是列表、单个对象、数字、布尔值等
        private T data;
    
        public Result() {
        }
    
        public Result(int resultCode, String message) {
            this.resultCode = resultCode;
            this.message = message;
        }
    
        public int getResultCode() {
            return resultCode;
        }
    
        public void setResultCode(int resultCode) {
            this.resultCode = resultCode;
        }
    
        public String getMessage() {
            return message;
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
    
        public T getData() {
            return data;
        }
    
        public void setData(T data) {
            this.data = data;
        }
    
        @Override
        public String toString() {
            return "Result{" +
                    "resultCode=" + resultCode +
                    ", message='" + message + '\'' +
                    ", data=" + data +
                    '}';
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    封装响应结果生成工具类

    /**
     * 响应结果生成工具
     *
     * @author supanpan
     * @create_date 2023-11-19 11:05
     */
    public class ResultGenerator {
        private static final String DEFAULT_SUCCESS_MESSAGE = "SUCCESS";
        private static final String DEFAULT_FAIL_MESSAGE = "FAIL";
        private static final int RESULT_CODE_SUCCESS = 200;
        private static final int RESULT_CODE_SERVER_ERROR = 500;
    
        public static Result genSuccessResult() {
            Result result = new Result();
            result.setResultCode(RESULT_CODE_SUCCESS);
            result.setMessage(DEFAULT_SUCCESS_MESSAGE);
            return result;
        }
    
        public static Result genSuccessResult(String message) {
            Result result = new Result();
            result.setResultCode(RESULT_CODE_SUCCESS);
            result.setMessage(message);
            return result;
        }
    
        public static Result genSuccessResult(Object data) {
            Result result = new Result();
            result.setResultCode(RESULT_CODE_SUCCESS);
            result.setMessage(DEFAULT_SUCCESS_MESSAGE);
            result.setData(data);
            return result;
        }
    
        public static Result genFailResult(String message) {
            Result result = new Result();
            result.setResultCode(RESULT_CODE_SERVER_ERROR);
            if (!StringUtils.hasText(message)) {
                result.setMessage(DEFAULT_FAIL_MESSAGE);
            } else {
                result.setMessage(message);
            }
            return result;
        }
    
        public static Result genErrorResult(int code, String message) {
            Result result = new Result();
            result.setResultCode(code);
            result.setMessage(message);
            return result;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    使用示例:

    /**
         * 商品列表
         * @return 统一返回对象
         */
        @RequestMapping(value = "/product/list",method = RequestMethod.GET)
        public Result list(
                @RequestParam(required = false) String goodsStatus,
                @RequestParam(required = false) String goodName,
                @RequestParam(required = false) Integer pageNum,
                @RequestParam(required = false) Integer pageSize){
            // 返回数据对象
            Object resultData = new Object();
            return ResultGenerator.genSuccessResult(resultData);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
  • 相关阅读:
    css如何实现页面布局与五种实现方式
    我的Vue之旅 09 数据数据库表的存储与获取实现 Mysql + Golang
    05-SA8155 QNX Hypervisor BSP之Interrupts中断
    Unity中的旋转和矩阵操作
    SpringMVC 拦截器
    c++(26) 输入输出流、文件操作
    spring mvc中如何设置log4j.xml的配置文件呢?
    OpenCV踩坑笔记使用笔记入门笔记整合SpringBoot笔记大全
    工业智能网关BL110应用之五十: 数据上传云金鸽Modbus的配置
    【flask框架】模型model
  • 原文地址:https://blog.csdn.net/weixin_45688141/article/details/134488738