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
悲观者正确,乐观者成功
原文地址:https://www.cnblogs.com/freebule/p/14462513.html