• swagger 框架使用


    Swagger的使用

    Swagger 简介

    存在问题:

    • 前后端分离,无法做到及时协商,及时解决

    解决方法:

    • 制定 schema【计划的提纲】,实时更新最新 API,降低集成的风险
    • 早些年:制定 word 计划文档;
    • 前后端分离:
      • 前端测试后端分离:postman
      • 后端提纲接口,需要实时最新的消息及改动

    Swagger

    • 号称世界上最流行的 API 框架,
    • 围绕 OpenAPI 规范构建的开源工具,RestFul API 文档在线生产工具=> Api文档与 API 定义同步更新
    • 直接运行,可以在线测试 API 接口
    • 支持多种语言(java,php。。。。)
    • 接口文档可以实时动态生成
    • 使用 Swagger,就是把相关的信息存储在它定义的描述文件里面 (yml 或 json 格式),再通过维护这个描述文件可以去更新接口文档, 以及生成各端代码

    Spring-fox

    • spring-fox是基于 spring 的组件,swagger-springmvc。 Spring-fox 就是根据这个组件发展而来的全新项目。
      Spring-fox 是根据代码生成接口文档,所以正常的进行更新项目版本,修改代码即可,而不需要跟随修改描述文件。
      Spring-fox 利用自身 AOP 特性,把 Swagger 集成进来,底层还是Swagger。但是使用起来确方便很多。
    • 是根据 swagger 的封装,完全根据代码生产接口文档,无须再修改描述文件

    所以在项目中使用 Swagger只需要使用 springbox即可

    • swagger2
    • ui

    SpringBoot 继承 Swagger

    1. 新建 SpringBoot web 项目
    2. 导入相关依赖
    <!--            swagger 依赖-->
                <dependency>
                    <groupId>io.springfox</groupId>
                    <artifactId>springfox-swagger2</artifactId>
                    <version>2.9.2</version>
                </dependency>
    
    <!--            swagger UI依赖-->
                <dependency>
                    <groupId>io.springfox</groupId>
                    <artifactId>springfox-swagger-ui</artifactId>
                    <version>2.9.2</version>
                </dependency>
    
    1. 编写项目
    @RestController
    @RequestMapping("/people")
    public class DemoController {
    
    
        @RequestMapping("/getpeople")
        public People getPeople(int id){
            People people = new People();
            people.setId(id);
            people.setName("北京");
            people.setAddress("朝阳");
            return people;
        }
    
    }
    
    1. 配置 Swagger,在启动类添加@EnableSwagger2,重启项目
    2. 测试运行 ui 地址 http://localhost:8080/swagger-ui.html

    配置 Swagger

    可以在项目中创建 SwaggerConfig,进行配置文档内容。就是对这部分进行配置

    配置基本信息

    • Docket:摘要对象,通过对象配置描述文件的信息。
    • apiInfo:设置描述文件中 info。参数类型 ApiInfo
    • select():返回 ApiSelectorBuilder 对象,通过对象调用 build()可以创建 Docket 对象
    • ApiInfoBuilder:ApiInfo 构建器。
    1. 创建项目配置文件
    @Configuration
    public class SwaggerConfig {
    
        @Bean
        public Docket getDocket() {
            return new Docket(DocumentationType.SWAGGER_2).apiInfo(getApiInfo()).select().build();
        }
    
        private ApiInfo getApiInfo() {
            return new ApiInfoBuilder()
                    .title("第一个 swagger 的标题")
                    .description("这里是描述")
                    .version("1.0.0")
                    //联系信息
                    .contact(new Contact("这是名称", "这是 url", "这是 email"))
                    .build();
        }
    }
    
    1. 结果

    设置扫描包

    • 通过 apis()方法设置哪个包中内容被扫描
     @Bean
        public Docket getDocket() {
            return new Docket(DocumentationType.SWAGGER_2)
                    .apiInfo(getApiInfo())
                    .select()
                    .apis(RequestHandlerSelectors.basePackage("com.example.swagger.controller"))
                    .build();
        }
    

    自定义接口不需要生成接口文档

    • 注解名称随意取
    @Target(ElementType.METHOD)//写在方法上
    @Retention(RetentionPolicy.RUNTIME)//运行时解析
    public @interface NotIncludeSwagger {
    }
    
    • 设置规则
    1. 通 过 public ApiSelectorBuilder apis(Predicate selector)可以设置生成规则。
    2. public static  Predicate not(Predicate predicate) :表示不 允许的条件。
    3. withMethodAnnotation:表示此注解是方法级别注解。
     @Bean
        public Docket getDocket() {
            return new Docket(DocumentationType.SWAGGER_2)
                    .apiInfo(getApiInfo())
                    .select()
                    .apis(RequestHandlerSelectors.basePackage("com.example.swagger.controller"))
                    .apis(not(withMethodAnnotation(NotIncludeSwagger.class)))//使用这个注解就不能实现接口文档
                    .build();
        }
    
    • 在不需要生成接口文档的方法上面添加@NotIncludeSwagger 注解后,该方法将不会被 Swagger 进行生成在接口文档中。

    设置范围

    • 通过 public ApiSelectorBuilder paths(Predicate selector)可 以设置满足什么样规则的 url 被生成接口文档。可以使用正则表达式 进行匹配。
    • 下面例子中表示只有以/people/开头的url 才能被 swagger 生成接口文档。也可以设置多个 url 地址
    • 如何希望全部扫描可以使用 paths(PathSelectors.any())
     @Bean
        public Docket getDocket() {
            return new Docket(DocumentationType.SWAGGER_2)
                    .apiInfo(getApiInfo())
                    .select()
                    .apis(RequestHandlerSelectors.basePackage("com.example.swagger.controller"))
                    .apis(not(withMethodAnnotation(NotIncludeSwagger.class)))//使用这个注解就不能实现接口文档
                    //设置一个
                    .paths(PathSelectors.regex("/people/.*"))
                   //设置多个 url 范围生成接口文档
                    .paths(or(PathSelectors.regex("/people/.*"),PathSelectors.regex("/demo/.*")))
                    .build();
        }
    

    Swagger 常用注解

    • API 注解
      @Api 是类上注解。控制整个类生成接口信息的内容。
      tags:类的名称。可以有多个值,多个值表示多个副本。
      description:描述,已过时。
      这个注解就是控制在 ui.html 页面的类名称和描述,只能用在类上
    @RestController
    @RequestMapping("/people")
    @Api(tags = {"mydemo"},description = "描述")
    public class DemoController {
    
        @PostMapping("/getpeople")
        public People getPeople(int id){
            People people = new People();
            people.setId(id);
            people.setName("北京");
            people.setAddress("朝阳");
            return people;
        }
    }
    
    • 页面显示内容修改前和添加 api 注解后

    • @ApiOperation 写在方法上,对方法进行总体描述
      value:接口描述
      notes:提示信息
     @ApiOperation(value = "获取人的内容",notes = "通过人的编号查询信息")
        public People getPeople(int id){
        }
    
    • @ApiParam
      @ApiParam 写在方法参数前面。用于对参数进行描述或说明是否 为必添项等说明。默认是参数名称
      name:参数名称
      value:参数描述
      required:是否是必须
    public People getPeople(@ApiParam(name = "这是 id",value = "这是 value",required = true) int id){
    }
    
    • ui 页面前后对比

    • ApiModel
      @ApiModel 是类上注解,主要应用 Model,也就是说这个注解一 般都是写在实体类上。
      value:名称
      description:描述
    @ApiModel(value = "人实体类",description = "实体类封装类 People 的全部属性")
    public class People {
    }
    

    • ApiModelProperty
      @ApiModelProperty 可以用在方法或属性上。用于当对象作为参 数时定义这个字段的内容。
      value:描述
      name:重写属性名
      required:是否是必须的
      example:示例内容
      hidden:是否隐藏,默认是 false 不隐藏
    public class People {
    
        @ApiModelProperty(value = "编号",name = "id",required = true,example = "123")
        private int id;
        private String name;
        @ApiModelProperty(hidden = true)
        private String address;
    }
    
    • ApiIgnore
      @ApiIgnore 用于方法或类或参数上,表示这个方法或类被忽略。 和之前讲解的自定义注解@NotIncludeSwagger 效果类似。只是这个注解是Swagger内置的注解,而@NotIncludeSwagger是我们自定义的注解。
    • ApiImplicitParam
      @ApiImplicitParam 用在方法上,表示单独的请求参数,总体功能 和@ApiParam (多数用于方法参数上) 类似。
      name:属性名
      value:描述
      required:是否是必须的
      paramType:属性类型
      dataType:数据类型
    @PostMapping("/getpeople2")
        @ApiImplicitParam(name = "id",value = "编号",paramType = "body",dataType = "int")//这个注解只能写一个
        public People getPeople1(int id,String name){
            return null;
        }
    
    @PostMapping("/getpeople2")
       @ApiImplicitParams(value ={@ApiImplicitParam(name = "id",value = "编号",required = true),@ApiImplicitParam(name = "name",value = "姓名")} )
        public People getPeople1(int id,String name){
            return null;
        }
    

    SpringBoot继承Swagger

    导入依赖

    编写一个 controller

    @RestController
    public class HelloController {
    
        @GetMapping("/hello")
        public String hello(){
            return "hello";
        }
    
        //只要接口中存在实体类就能扫描到
        @PostMapping("/hi")
        public User user(){
            return new User();
        }
    
    
        @ApiOperation("user方法")//用在方法上
        @PostMapping("/user")
        public String user1(@ApiParam("传入姓名参数") String name){
            return name;
        }
    }
    

    swagger 配置文件

    Swagger 的 bean 实例 Docket

    @Configuration
    @EnableSwagger2//开启 swagger2
    public class SwaggerConfig {
    
        //配置 swagger 的 bean 实例
        @Bean
        public Docket docket(){
            return  new Docket(DocumentationType.SWAGGER_2)
                    .apiInfo(apiInfo());
        }
    
        public ApiInfo apiInfo(){
            return new ApiInfo(
                    "Swagger 文档",
                    "学好 swagger",
                    "1.0",
                    "http://www.baidu.com/",
                    new Contact("本人", "http://www.baidu.com/", "714860063@qq.com"),
                    "Apache 2.0",
                    "http://www.apache.org/licenses/LICENSE-2.0",
                    new ArrayList());
        }
    }
    

    Swagger 配置扫描接口

    @Configuration
    @EnableSwagger2//开启 swagger2
    public class SwaggerConfig {
    
        //配置 swagger 的 bean 实例
        @Bean
        public Docket docket(){
            return  new Docket(DocumentationType.SWAGGER_2)
                    .apiInfo(apiInfo())
                    .select()
                    //RequestHandlerSelectors,配置要扫描接口的方式
                    //basePackage:指定 扫描包;none() ,不扫描
                    //withClassAnnotation :扫描类上注解 比如:@RestController
                    //withMethodAnnotation :扫描类上注解 比如: @RequestMapping()
                    
                    .apis(RequestHandlerSelectors.basePackage("com.study.controller"))
                    .paths(PathSelectors.ant("/study/**"))//过滤路径
                    .build();
        }
    
        public ApiInfo apiInfo(){
            return new ApiInfo(
                    "Swagger 文档",
                    "学好 swagger",
                    "1.0",
                    "http://www.baidu.com/",
                    new Contact("本人", "http://www.baidu.com/", "714860063@qq.com"),
                    "Apache 2.0",
                    "http://www.apache.org/licenses/LICENSE-2.0",
                    new ArrayList());
        }
    }
    

    配置是否启动 swagger

    //配置 swagger 的 bean 实例
    @Bean
    public Docket docket(){
        return  new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .enable(false)//是否启用 swagger,false 则不能在浏览器访问
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.study.controller"))
                .build();
    }
    

    如何动态配置在不同环境中是否启用 swagger

    @Configuration
    @EnableSwagger2//开启 swagger2
    public class SwaggerConfig {
    //配置 swagger 的 bean 实例
        @Bean
        public Docket docket(Environment environment){
            //配置文件中的生成环境 spring.profiles.active=dev
    
            //设置要显示的 swagger,一般生成环境,需要设置
            Profiles profiles = Profiles.of("dev", "test");
            //判断是否在设置的生产环境中
            boolean flag = environment.acceptsProfiles(profiles);
            System.out.println(flag);
            return  new Docket(DocumentationType.SWAGGER_2)
                    .groupName("张三")
                    .apiInfo(apiInfo())
                    .enable(flag)//是否启用 swagger,false 则不能在浏览器访问
                    .select()
                    .apis(RequestHandlerSelectors.basePackage("com.study.controller"))
                    .build();
        }
    }
    

    配置 API 文档分组

    (多人开发时,每个人维护自己的组即可),配置多个组就配置不同名的 Docke 就可以实现

    @Bean
    public Docket docket1(){
        return  new Docket(DocumentationType.SWAGGER_2)
                .groupName("李四");
    }
    

    常用的注解

    //ApiModel 是为了写个注释
    @ApiModel("用户实体类")//用在实体类
    public class User {
    
        @ApiModelProperty("用户名")//用在属性上
        public int id;
        @ApiModelProperty("密码")
        public String name;
    }
    
    @RestController
    public class HelloController {
    
        @GetMapping("/hello")
        public String hello(){
            return "hello";
        }
    
        //只要接口中存在实体类就能扫描到
        @PostMapping("/hi")
        public User user(){
            return new User();
        }
    
    
        @ApiOperation("user方法")//用在方法上
        @PostMapping("/user")
        public String user1(@ApiParam("传入姓名参数") String name){
            return name;
        }
    }
    

    测试功能

    总结:

    1. 我们可以通过 swagger 给一些比较难理解的属性或接口,增加注释信息
    2. 接口文档的实时更新
    3. 可以在线测试
    4. !!!注意点:正式发布时候关闭 swagger
    悲观者正确,乐观者成功
  • 相关阅读:
    学习笔记
    js闭包
    一个非必现问题的定位和反思
    C语言的设计模式面向对象机制的实现(一)
    多线程和单线程的执行效率问题
    python 多态
    C语言的设计模式接口隔离
    构建表达式二叉树
    C语言的设计模式依赖倒置
    C语言的设计模式单一职责
  • 原文地址:https://www.cnblogs.com/freebule/p/14462513.html
Copyright © 2020-2023  润新知