Swagger返回嵌套json数据

一、接口展示中的问题

  现在大部分前后端的数据交互都是采用json格式,如我们经常用一个大的json包裹着数据发送的,但是在Swagger中,如果直接返回这个类对象,是展示不了data里面的数据的,更谈不上嵌套的json了,所以,为了让它能展示出data中的数据类型及格式,我们可以使用Java的泛型来做。

{
  "code": 0,
  "data": {},
  "msg": "string"
}

二、BaseResult工具类

  首先,我们要制定一个用于所有返回数据的最外层json框架的工具类,但是这个时候不能直接写这个类了,因为我们想在Swagger中显示内层数据的格式。Swagger是通过反射机制来展现类内部信息的,如果它只会返回一层数据的详细类型,即使类里面包含了其他类的对象,也不会再深入展示了,所以为了让它知道内部还有一个类对象要展示,那要传入这个对象的类型信息,所以要用到泛型。

package com.sc.springboot.utils;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

import java.io.Serializable;

//和以前唯一不一样的地方就是加了一个泛型T
@ApiModel("通用返回对象")  //注释这个类的信息
public class BaseResult<T> implements Serializable {
    //解释各字段的意思
    @ApiModelProperty(value = "返回码", dataType = "String")
    private int code;
    @ApiModelProperty(value = "提示信息", dataType = "String")
    private String msg;
    @ApiModelProperty(value = "返回值", dataType = "String")
    private T data;

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    //几种构造方法
    public BaseResult() {
    }

    public BaseResult(BaseResult.Type type, String msg) {
        this.code = type.value;
        this.msg = msg;
    }

    public BaseResult(BaseResult.Type type, String msg, T data) {
        this.code = type.value;
        this.msg = msg;
        if (data != null) {
            this.data = data;
        }

    }
    //静态方法要使用泛型参数的话,要声明其为泛型方法
    public static <T> BaseResult<T> success() {
        return success("操作成功");
    }

    public  static <T> BaseResult<T> success(T data) {
        return success("操作成功", data);
    }

    public static <T> BaseResult<T> success(String msg) {
        return success(msg, (T) null);
    }

    public static <T> BaseResult<T> success(String msg, T data) {
        return new BaseResult<T>(BaseResult.Type.SUCCESS, msg, data);
    }

    public static <T> BaseResult<T> warn(String msg) {
        return warn(msg, (T) null);
    }

    public static <T> BaseResult<T> warn(String msg, T data) {
        return new BaseResult<T>(BaseResult.Type.WARN, msg, data);
    }


    public static <T> BaseResult<T> unAuth() {
        return new BaseResult<T>(Type.UNAUTH, "未登陆", (T)null);
    }

    public static <T> BaseResult<T> error() {
        return error("操作失败");
    }

    public static <T> BaseResult<T> error(String msg) {
        return error(msg, (T)null);
    }

    public static <T> BaseResult<T> error(String msg, T data) {
        return new BaseResult<T>(BaseResult.Type.ERROR, msg, data);
    }

    public static enum Type {
        SUCCESS(200),
        WARN(402),
        UNAUTH(401),
        ERROR(500);

        private final int value;

        private Type(int value) {
            this.value = value;
        }

        public int value() {
            return this.value;
        }
    }
}

这里编写的BaseResult类可以直接在工程中使用,和以前唯一的不同就是,在BaseResult返回值上带一个具体的data类型

三、使用BaseResult

1. 对应一个url该怎么返回数据

  唯一的变化就是,在返回的BaseResult需要加上你要返回的泛型参数即可

@ApiOperation("获取登录用户信息")
@ApiImplicitParams({
        @ApiImplicitParam(name = "token", value = "token信息", paramType = "header")
})
@ApiResponses({
        @ApiResponse(code=200,message = "请求成功"),
        @ApiResponse(code=401,message = "未登陆"),
})
@GetMapping("getuserinfo")
public BaseResult<Supplier> getUserOfLogin(HttpServletRequest request) throws UnsupportedEncodingException {
    //获取Headers中的参数
    String token = request.getHeader("token");
    //获取header,这是从Redis中获取登录信息
    Supplier user = (Supplier) redisTemplate.opsForValue().get(token);
    if(user != null){
        return BaseResult.success(user);
    }
    return BaseResult.unAuth();
}
2. swagger中的数据展示

在这里插入图片描述
在这里插入图片描述

  这样的返回信息,已经很棒了,但是有时候我们的json有会嵌套很多层,那么我们就需要嵌套多层泛型。

四、多层嵌套

1. 嵌入一层列表

  比如,我们返回的不知一个用户信息了,想返回一个列表,可以直接用泛型表示列表就行了

@GetMapping("/getuserlist")
private BaseResult<List<Supplier> > getUser(){
    List<Supplier> supplier = new LinkedList<>();
    return BaseResult.success(supplier);
}

在这里插入图片描述
在这里插入图片描述

2. 返回分页信息

  这种情况很常见,比如,我们要给数据分页,就得给出一个列表和一些页数信息,当前页,最大页等。
  我们可以单独创建一个分页类

package com.lonelyzhe.sc.bean;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

@ApiModel("分页类型")
public class DivPage<T> {
    @ApiModelProperty(value = "当前页数", dataType = "Integer")
    private Integer current_page;
    @ApiModelProperty(value = "最大页数", dataType = "Integer")
    private Integer max_page;
    @ApiModelProperty(value = "当前内容", dataType = "List")
    private T content;
    //省去了set、get方法,可以写上,或者用注解都行
}

  返回的时候,填写DivPage的泛型参数就行了

@GetMapping("/getpagelist")
private BaseResult<DivPage<List<Supplier>> > getUser(){
    List<Supplier> supplier = new LinkedList<>();
    DivPage<List<Supplier>> divPage = new DivPage<>();
    divPage.setCurrent_page(1);
    divPage.setMax_page(20);
    divPage.setContent(supplier);

    return BaseResult.success(divPage);
}

在这里插入图片描述
在这里插入图片描述

3. 对象里有另外的对象

  这种情况其实也挺多的,比如我们的用户有一个公司属性,但这个公司属性也是个对象,有公司id,公司名等,现在也要完整展示公司的信息,相当于嵌套里面有嵌套,其实和分页差不多,只是分页用的List本身就是泛型的,所以为了展示我们自己对象里的对象,需要把第一层对象设置为泛型。
(1)添加一个Company类

package com.lonelyzhe.sc.bean;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

@ApiModel(value = "公司")
public class Company {
    @ApiModelProperty(value = "公司id", dataType = "Integer")
    private Integer id;
    @ApiModelProperty(value = "公司名", dataType = "String")
    private String name;
    //省略get、set方法
}

(2)修改Supplier类,使其接收泛型参数

package com.lonelyzhe.jedisdemo.bean;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

@ApiModel(value = "供应商信息")
public class Supplier<T>{  //这里多加一个泛型参数
    @ApiModelProperty(value = "供应商id", dataType = "int")
    private Integer supplier_id;
    @ApiModelProperty(value = "供应商名称", dataType = "String")
    private String supplier_name;
    @ApiModelProperty(value = "一级分类", dataType = "String")
    private String primary_supplier;
    @ApiModelProperty(value = "二级分类", dataType = "String")
    private String secondary_supplier;
    @ApiModelProperty(value = "三级分类", dataType = "String")
    private String tertiary_supplier;
    @ApiModelProperty(value = "所属公司", dataType = "Company")
    private Company company;
}

(3)返回结果
在这里插入图片描述
在这里插入图片描述
  如果有很多层对象封装的话,那么每一层都需要泛型参数,如果一层中有多个封装的对象,那么可能要传入多个泛型参数。

五、总结

  刚开始接触swagger有点懵,为啥返回不了里面的类的字段呀,后来查阅了很多资料,说得用泛型,又回想到Java编程思量里管理泛型和反射的章节,感觉swagger返回参数的时候应该是只读取了一层类型,如果类里面还包含其他的类对象,它就不知道具体类型是什么,此时需要用泛型去指定这个参数,让它知道类内部对象的类型才行。
  当然,这只是最近研究的方法,如果有更好的方法就好,毕竟给每个类都加上泛型,还是麻烦的,增加了开发成本,不过相较于最后的自动Api结果,依然是真香!

  • 12
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Swagger 是一种用于构建、设计和文档化 RESTful API 的工具。它提供了一个简单易用的界面,让开发者可以定义 API 的各种细节,包括端点、参数、请求和响应等。Swagger 还可以根据用户的定义自动生成 OpenAPI JSON,这是一种机器可读的 API 文档格式。 Swagger 生成 OpenAPI JSON 的过程非常简单。首先,我们需要在 Swagger 的配置文件或注解中定义我们的 API。在定义 API 时,我们需要指定每个端点的路径、请求方法、请求参数、请求体和响应内容等。为了使生成的 OpenAPI JSON 更加准确和完整,我们还可以添加其他的元数据,比如 API 的标题、描述、版本号等。 当我们完成 API 的定义后,我们可以使用 Swagger 提供的工具自动生成 OpenAPI JSON。通常,我们只需要运行一条命令或点击一个按钮,Swagger 就会根据我们的定义扫描我们的 API,并生成一份符合 OpenAPI 规范的 JSON 文件。这份文件包含了 API 的详细信息,包括端点的路径、请求方法、请求和响应的参数等。生成的 JSON 文件可以供其他开发者和工具使用,比如用于生成文档、进行代码生成等。 总之,Swagger 是一个强大的工具,可以帮助我们快速构建、设计和文档化 RESTful API。通过定义 API,并使用 Swagger 提供的工具生成 OpenAPI JSON,我们可以更方便地与其他开发者进行协作,并提供高质量的 API 文档。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值