美文网首页springbootSpring bootSpring cloud
Swagger注解释义与SpringBoot的集成

Swagger注解释义与SpringBoot的集成

作者: 程er狗 | 来源:发表于2018-11-04 22:56 被阅读94次

    成为一个不可替代的人!
                                    ——程二狗


    导读

    当你好不容易写完接口,你以为已经完事,老大却突然说,接口文档也要写。oh,my God!我快要疯了,然而还是要戳着头发写完。现在好了,Swagger文档让你加少量的注解,自动帮你生成接口文档,系不系很开心ing。当然Swagger也有缺点,为了文档而写很多的Vo类、param类=。

    一、Swagger基础介绍

    1.什么是Swagger
      描述REST API格式的一组规则(规范),OpenAPI(几十个知名互联网公司定制的API文档规范,Swagger就是其实现之一)的前身。Swagger让测试人员和开发人员之间文档共享。用于前后端分离,接口管理和测试工具集。
    2.能做什么
      2.1.接口的文档在线自动生成
      2.2.功能测试
    3.版本
      3.1.Swagger1(很少用)
      3.2.Swagger2(常用)
      3.3.springfox-swagger2(用的最多)
    三者关系:Swagger2是Swagger1的升级版。spring公司把swagger集成到自己的项目里,整了一个spring-swagger,后来便演变成springfox。springfox本身只是利用自身的aop的特点,通过plug的方式把swagger集成了进来,它本身对业务api的生成,还是依靠swagger来实现。
    4.Swagger主要工具


    Swagger编辑器:一个基于浏览器的编辑器,您可以在其中编写OpenAPI规范。
    Swagger-core: 用于Java/Scala的的Swagger实现。与JAX-RS(Jersey、Resteasy、CXF...)、Servlets和Play框架进行集成。
    Swagger-ui:一个无依赖的HTML、JS和CSS集合,可以为Swagger兼容API动态生成优雅文档。
    Swagger-codegen:一个模板驱动引擎,通过分析用户Swagger资源声明以各种语言生成客户端代码。

    二、注解说明

    注解 使用位置 取值 说明
    @Api 用于Controller类上 协议集描述
    value url的路径位置
    tags 设置该值,value值被覆盖
    description 对api资源的描述(过时)
    basePath 基本路径可以不配置(过时)
    position 如果配置了多个Api,可用该注解改变显示顺序(过时)
    produces For example, "application/json, application/xml"
    consumes For example, "application/json, application/xml"
    protocols Possible values: http, https, ws, wss
    authorizations 高级特性认证时配置
    hidden 配置为true 将在文档中隐藏
    @ApiModel 用在返回对象类上 对返回对象的描述
    value 为模型提供一个替代名称,默认使用类名
    description 提供一个更长的类描述
    parent 为模型提供一个超类以允许描述继承
    discriminator 支持模型继承和多态性,这是用作鉴别器的字段的名称,基于这个字段,可以断言需要使用哪个子类型
    subTypes 继承自此模型的子类型的数组
    reference 指定对相应类型定义的引用,覆盖指定的任何其他元数据
    @ApiImplicitParam 用在controller的方法上 对API操作中的单个参数进行定义
    name 参数的名称
    value 参数的简要描述
    defaultValue 描述参数的默认值
    allowableValues 限制此参数的可接受值
    required 指定是否需要参数,默认false
    access 允许从API文档中过滤参数
    allowMultiple 指定参数是否可以接受多个逗号分隔的值
    dataType 参数的数据类型,可以是类名或基元
    dataTypeClass url的路径位置
    paramType 参数的参数类型,有效值是路径、查询、正文、标题或表单
    example 非主体类型参数的一个示例
    examples 参数示例。仅适用于body参数
    type 添加覆盖检测到的类型的能力
    format 添加提供自定义格式的功能
    format 添加提供自定义格式的功能
    allowEmptyValue 添加将格式设置为空的功能
    collectionFormat 添加使用' array '类型覆盖collectionFormat的功能
    @ApiImplicitParams 用在@ApiImplicitParams的方法里边 允许多个ApiImplicitParam对象列表的包装器,参看@ApiImplicitParam注解
    @ApiModelProperty 用在出入参数对象的字段上 描述对象属性
    value 属性的简要描述
    name 允许重写属性的名称
    access 允许从API文档中过滤参数
    allowableValues 限制此属性的可接受值
    notes 目前未使用
    dataType 参数的数据类型,这可以是类名或基元。该值将覆盖从类属性读取的数据类型
    required 指定是否需要参数,默认false
    position 允许显式地对模型中的属性进行排序
    hidden 允许模型属性隐藏在Swagger模型定义中
    example 属性的示例值
    readOnly 允许模型属性被指定为只读
    reference 指定对相应类型定义的引用,覆盖指定的任何其他元数据
    allowEmptyValue 允许传递空值
    @ApiOperation 用在controller的方法上 用来描述方法的作用
    value 操作的简要描述
    notes 操作的详细描述
    tags 标记可用于根据资源或任何其他限定符对操作进行逻辑分组,会覆盖value值
    response 操作的响应类型
    responseContainer 声明一个容器,有效值是“List”、“Set”或“Map”。其他任何值都将被忽略
    responseReference 指定对响应类型的引用,覆盖任何指定的response()类
    httpMethod 指定一种请求方式
    position (过时)
    nickname 第三方工具使用operationId来惟一地标识该操作
    produces 对应于操作的“生成”字段,接受内容类型的逗号分隔值。例如,“application/json, application/xml”将建议此操作生成json和xml输出。
    consumes 接受内容类型的逗号分隔值。例如,“application/json, application/xml”将建议此API资源接受json和xml输入
    protocols 为该操作设置特定的协议(方案),可用协议的逗号分隔值。可能的值:http、https、ws、wss。
    authorizations 获取此操作的授权(安全需求)列表
    hidden 从操作列表中隐藏操作
    responseHeaders 响应可能提供的响应头列表
    code 响应状态码,默认200
    extensions 可选的扩展数组
    @ApiParam 用在Controller类的方法上
    name 参数名称
    value 参数简要描述
    defaultValue 参数的默认值
    allowableValues 限制可接受参数
    required 指定是否需要参数,默认false
    access 允许从API文档中过滤参数
    allowMultiple 指定参数是否可以通过多次出现来接受多个值
    hidden 从参数列表中隐藏参数
    example 非主体类型参数的一个示例
    examples 参数示例。仅适用于body参数
    type 添加覆盖检测到的类型的能力
    format 添加提供自定义格式的功能
    allowEmptyValue 添加将格式设置为empty的功能
    readOnly 增加被指定为只读的能力
    collectionFormat 添加使用' array '类型覆盖collectionFormat的功能
    @ApiResponse 用在 @ApiResponses里边 返回单个结果集(类)说明
    code 状态码,默认200
    message 返回响应信息
    response 可选的响应类来描述消息的有效负载
    reference 指定对响应类型的引用,覆盖任何指定的response()类
    responseHeaders 响应可能提供的响应头列表
    responseContainer 声明一个响应容器,有效值是“List”、“Set”或“Map”。其他任何值都将被忽略
    @ApiResponses 用在controller的方法上 返回结果集说明,参考@ApiResponse
    @Authorization 用在controller的方法上 定义用于资源或操作的授权方案
    value 用于此资源/操作的授权方案的名称
    scopes 如果授权模式是OAuth2,则使用的作用域
    @AuthorizationScope 用在controller的方法上 用于定义为已定义授权方案的操作所使用的授权范围
    scope 使用OAuth2授权方案的范围,作用域应该在Swagger对象的securityDefinition部分中预先声明
    description 用于遗留支持
    @ResponseHeader 用在controller的方法上 响应可能提供的响应头列表
    name 响应头的名字
    description 响应头的长描述
    response 响应头的数据类型
    responseContainer 声明一个响应容器,有效值是“List”、“Set”或“Map”。其他任何值都将被忽略

    参考:1.Swagger在gitHub上的wiki
       2.官网注解文档
    allowableValues
    限制此属性的可接受值,有三种方法来描述允许的值:
    若要设置值列表,请提供一个用逗号分隔的列表,并用方括号括起来。例如:[第一,第二,第三]。
    要设置一个值范围,以“range”开头,用方括号括起最小值和最大值。例如:range[1,5]。
    要设置最小/最大值,对range使用相同的格式,但使用“无穷大”或“-无穷大”作为第二个值。例如,range[1, infinity]表示该参数的最小允许值为1。

    三、与springBoot的集成

    如果你还不会快速构建一个springBoot项目,参看我的另一篇文章:springBoot入门简单Demo

    3.1.引入jar包

    <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger2</artifactId>
                <version>2.8.0</version>
            </dependency>
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger-ui</artifactId>
                <version>2.8.0</version>
            </dependency>
    

    3.2.创建Swagger配置类

    package com.ergou.springswagger.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import springfox.documentation.builders.ApiInfoBuilder;
    import springfox.documentation.builders.PathSelectors;
    import springfox.documentation.builders.RequestHandlerSelectors;
    import springfox.documentation.service.ApiInfo;
    import springfox.documentation.service.Contact;
    import springfox.documentation.spi.DocumentationType;
    import springfox.documentation.spring.web.plugins.Docket;
    import springfox.documentation.swagger2.annotations.EnableSwagger2;
    
    /**
     * Swagger的配置类
     * @create by 程二狗 on 2018/11/4 0004
     **/
    
    @Configuration//配置类
    @EnableSwagger2//启用Swagger
    public class SwaggerConfig {
        @Bean//加入到spring的容器中
        public Docket createRestApi() {
            return new Docket(DocumentationType.SWAGGER_2)
                    .pathMapping("/")
                    .select()
                    .apis(RequestHandlerSelectors.basePackage("com.ergou.springswagger.controller"))//需要扫描的包路径
                    .paths(PathSelectors.any())
                    .build()
                    .apiInfo(testApiInfo());
        }
    
        private ApiInfo testApiInfo() {
            return new ApiInfoBuilder()
                    .title("springBoot集成swagger构建api文档")//标题
                    .description("详细描述")//详细描述
                    .version("1.0")//版本
                    .termsOfServiceUrl("服务地址")
                    .contact(new Contact("程二狗","https://www.jianshu.com/u/c612609d99d8","chengbotao152@163.com"))//作者的一些信息
                    .license("The Apache License, Version 2.0")//发布遵循协议
                    .licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html")//协议地址
                    .build();
        }
    }
    

    3.3.测试

    在浏览器中输入:http://localhost:8080/swagger-ui.html,端口号改成自己配置的。

    成功页面


    主要测试类

    package com.ergou.springswagger.controller.student;
    
    import com.ergou.springswagger.controller.student.param.*;
    import com.ergou.springswagger.controller.student.vo.PageInfoStudent;
    import com.ergou.springswagger.controller.student.vo.StudentMapVo;
    import com.ergou.springswagger.controller.student.vo.StudentVo;
    import com.ergou.springswagger.entity.ApiRes;
    import com.ergou.springswagger.entity.PageInfo;
    import com.ergou.springswagger.entity.Student;
    import com.ergou.springswagger.service.StudentService;
    import io.swagger.annotations.*;
    import net.bytebuddy.asm.Advice;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;
    
    import java.util.*;
    
    
    /**
     * @create by 程二狗 on 2018/10/28 0028
     **/
    @RestController
    @Api(tags = {"学生类操作"})//默认是student-controller
    @RequestMapping("/student")
    public class StudentController {
        @Autowired
        StudentService studentService;
        //如果我不指定httpMethod,会生成很多请求方式的文档,例如get、post、put==
        //当然我如果@PostMapping或者这样@RequestMapping(value = "/add",method = RequestMethod.GET)指定
        //就无需再指定如果我不指定httpMethod
        @ApiOperation(value = "添加学生",httpMethod = "POST")
        @RequestMapping("/add")
        @ApiResponses({@ApiResponse(code = 200,message = "success")})
        public ApiRes add(@RequestBody StudnetParam param){
            return com.ergou.springswagger.entity.ApiResponse.success();
        }
    
        @ApiOperation("删除学生")
        //我这儿没有指定请求方式,注意看生成的文档
        @RequestMapping("/delete")
        @ApiResponses({@ApiResponse(code = 200,response = Student.class,message = "success")})
        public ApiRes delete(@RequestBody StudnetIdParam param){
            return com.ergou.springswagger.entity.ApiResponse.success();
        }
    
        @ApiOperation("更新学生")
        @PostMapping("/update")
        @ApiResponses({@ApiResponse(code = 200,response = Student.class,message = "success")})
        public ApiRes update(@RequestBody StudnetParam param){
            return com.ergou.springswagger.entity.ApiResponse.success();
        }
    
        @ApiOperation("查看学生详情")
        @PostMapping("/get")
        @ApiResponses({@ApiResponse(code = 200,response = Student.class,message = "success")})
        public ApiRes get(@RequestBody StudnetIdParam param){
            return com.ergou.springswagger.entity.ApiResponse.success(studentService.get((long)1));
        }
    
        //==================重点:以下主要测试@ApiResponses注解==================
        //返回List指定
        //指定responseContainer,response指定类型
        @ApiOperation("获取学生列表")
        @PostMapping("/getList")
        @ApiResponses({@ApiResponse(code = 200,responseContainer = "List",response = Student.class,message = "success")})
        public ApiRes getList(@RequestBody StudnetGetListParam param){
            return com.ergou.springswagger.entity.ApiResponse.success(studentService.getList());
        }
        //返回Map指定测试
        //我的做法:构建一个vo类,去包含这些属性
        @ApiOperation("返回map结果集测试")
        @PostMapping("/getMap")
        @ApiResponses({@ApiResponse(code = 200,response = StudentMapVo.class,message = "success")})
        public ApiRes getMap(@RequestBody StudnetGetListParam param){
    
            //构建数据
            List<StudentVo> studentListVo = new ArrayList<>(4);
            studentListVo.add(new StudentVo((long)1,"程二狗", 18, (byte) 1, new Date()));
            studentListVo.add(new StudentVo((long)2,"陈雪峰", 18, (byte) 1, new Date()));
            studentListVo.add(new StudentVo((long)3,"张金洲", 18, (byte) 1, new Date()));
            studentListVo.add(new StudentVo((long)4,"赵楠", 18, (byte) 1, new Date()));
    
            Map<String,Object> studentMap = new HashMap(4){{
                put("countInteger",1);
                put("studentVo",new StudentVo((long)1,"程二狗", 18, (byte) 1, new Date()));
                put("countByte",(byte) 2);
                put("studentVoList",studentListVo);
            }};
            return com.ergou.springswagger.entity.ApiResponse.success(studentMap);
        }
    
        //返回PageInfo<T>指定
        //我的做法:构建一个vo类,去继承该类,然后指定response
        @ApiOperation("返回PageInfo<T>测试")
        @PostMapping("/getPageInfo")
        @ApiResponses({@ApiResponse(code = 200,response = PageInfoStudent.class, message = "success")})
        public ApiRes getPageInfo(@RequestBody StudnetGetListParam param){
            PageInfo<StudentVo> pageInfo = new PageInfo<>();
            pageInfo.setTotal(2000000);
            return com.ergou.springswagger.entity.ApiResponse.success(pageInfo);
        }
    
    }
    

    一些注解解释

    @Api

    @ApiModel


    @ApiOperation


    PS:其余的注解网上已经很多了,我就不再写了,你一百度就能找到

    四、本文重点: @ApiResponses:返回结果集List、Set(同List)、Map、PageInfo如何处理???

     //==================重点:以下主要测试@ApiResponses注解==================
        //返回List指定
        //指定responseContainer,response指定类型
        @ApiOperation("获取学生列表")
        @PostMapping("/getList")
        @ApiResponses({@ApiResponse(code = 200,responseContainer = "List",response = Student.class,message = "success")})
        public ApiRes getList(@RequestBody StudnetGetListParam param){
            return com.ergou.springswagger.entity.ApiResponse.success(studentService.getList());
        }
        //返回Map指定测试
        //我的做法:构建一个vo类,去包含这些属性
        @ApiOperation("返回map结果集测试")
        @PostMapping("/getMap")
        @ApiResponses({@ApiResponse(code = 200,response = StudentMapVo.class,message = "success")})
        public ApiRes getMap(@RequestBody StudnetGetListParam param){
    
            //构建数据
            List<StudentVo> studentListVo = new ArrayList<>(4);
            studentListVo.add(new StudentVo((long)1,"程二狗", 18, (byte) 1, new Date()));
            studentListVo.add(new StudentVo((long)2,"陈雪峰", 18, (byte) 1, new Date()));
            studentListVo.add(new StudentVo((long)3,"张金洲", 18, (byte) 1, new Date()));
            studentListVo.add(new StudentVo((long)4,"赵楠", 18, (byte) 1, new Date()));
    
            Map<String,Object> studentMap = new HashMap(4){{
                put("countInteger",1);
                put("studentVo",new StudentVo((long)1,"程二狗", 18, (byte) 1, new Date()));
                put("countByte",(byte) 2);
                put("studentVoList",studentListVo);
            }};
            return com.ergou.springswagger.entity.ApiResponse.success(studentMap);
        }
        //返回PageInfo<T>指定
        //我的做法:构建一个vo类,去继承该类,然后指定response
        @ApiOperation("返回PageInfo<T>测试")
        @PostMapping("/getPageInfo")
        @ApiResponses({@ApiResponse(code = 200,response = PageInfoStudent.class, message = "success")})
        public ApiRes getPageInfo(@RequestBody StudnetGetListParam param){
            PageInfo<StudentVo> pageInfo = new PageInfo<>();
            pageInfo.setTotal(2000000);
            return com.ergou.springswagger.entity.ApiResponse.success(pageInfo);
        }
    

    List(Set)

    Map

    package com.ergou.springswagger.controller.student.vo;
    
    import io.swagger.annotations.ApiModel;
    import io.swagger.annotations.ApiModelProperty;
    
    import java.io.Serializable;
    import java.util.List;
    
    /**
     * 返回Map结果集测试
     * @create by 程二狗 on 2018/11/4 0004
     **/
    @ApiModel("map")//默认是StudentMapVo,注意看我指定后在界面上是啥样
    public class StudentMapVo implements Serializable {
         //注意:属性值必须和你map中的key一致
          @ApiModelProperty("map测试Integer属性")
          private Integer countInteger;
          @ApiModelProperty("map测试单对象属性")
          private StudentVo studentVo;
          @ApiModelProperty("map测试Byte属性")
          private Byte countByte;
          @ApiModelProperty("map测试List属性")
          private List<StudentVo> studentListVo;
    
        public Integer getCountInteger() {
            return countInteger;
        }
    
        public void setCountInteger(Integer countInteger) {
            this.countInteger = countInteger;
        }
    
        public StudentVo getStudentVo() {
            return studentVo;
        }
    
        public void setStudentVo(StudentVo studentVo) {
            this.studentVo = studentVo;
        }
    
        public Byte getCountByte() {
            return countByte;
        }
    
        public void setCountByte(Byte countByte) {
            this.countByte = countByte;
        }
    
        public List<StudentVo> getStudentListVo() {
            return studentListVo;
        }
    
        public void setStudentListVo(List<StudentVo> studentListVo) {
            this.studentListVo = studentListVo;
        }
    }
    
    

    PageInfo<T>

    package com.ergou.springswagger.controller.student.vo;
    
    import com.ergou.springswagger.entity.PageInfo;
    import com.ergou.springswagger.entity.Student;
    
    /**
     * @create by 程二狗 on 2018/11/4 0004
     **/
    public class PageInfoStudent extends PageInfo<StudentVo> {
    }
    

    另外我还写了一个User类,和Student类差不多,供大家自行去测试,本文代码百度网盘
    链接:https://pan.baidu.com/s/11qmZcE9BBH_cIYa2K5lvQQ
    提取码:xkfl

    文中若有错误欢迎指正,感谢!后续过程中我也会不断完善


                  《刹那芳华曲》
    朝露昙花
    咫尺天涯,人道是黄河十曲,毕竟东流去。
    八千年玉老,一夜枯荣,问苍天此生何必?
    昨夜风吹处,落英听谁细数。
    九万里苍穹,御风弄影,谁人与共?
    千秋北斗,瑶宫寒苦,不若神仙眷侣,百年江湖。
                          程二狗摘自树下野狐《搜神记》


    相关文章

      网友评论

        本文标题:Swagger注解释义与SpringBoot的集成

        本文链接:https://www.haomeiwen.com/subject/ydkhxqtx.html