SpringBoot-Web-集成Swagger

Swagger简介

前后端分离

  • 前端 -> 前端控制层、视图层

  • 后端 -> 后端控制层、服务层、数据访问层

  • 前后端通过API进行交互

  • 前后端相对独立且松耦合

产生的问题

  • 前后端集成,前端或者后端无法做到“及时协商,尽早解决”,最终导致问题集中爆发

解决方案

  • 首先定义schema [ 计划的提纲 ],并实时跟踪最新的API,降低集成风险

  • Swagger

    • 号称世界上最流行的API框架

    • Restful Api 文档在线自动生成器 => API 文档 与API 定义同步更新

    • 直接运行,在线测试API

    • 支持多种语言 (如:Java,PHP等)

    • 官网:https://swagger.io/

SpringBoot集成Swagger

使用Swagger

1. SpringBoot集成Swagger => springfox,两个jar包

  • Springfox-swagger2
  • swagger-springmvc
       <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
       <!-- 经测试,3.0.0不能启动swagger -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>

2. 编写controller接口测试接口是否能正常运行

package com.qk.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {
    
    
    @RequestMapping("/t1")
    public String test01(){
    
    
        return "hello swagger";
    }
}

在这里插入图片描述

3. 编写配置类,开启swagger2

package com.qk.config;

import org.springframework.context.annotation.Configuration;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class HelloSwagger {
    
    

}

  • 访问:http://localhost:8080/swagger-ui.html

在这里插入图片描述

配置Swagger

1. 查看源码分析

在这里插入图片描述

2. 综上

@Configuration
@EnableSwagger2
public class HelloSwagger {
    
    
    //配置swagger的Docket的bean实例
    @Bean
    public Docket docket(){
    
    
        return new Docket(DocumentationType.SWAGGER_2);
    }

}

3. 在Docket中的除了参数DocumentationType,其他参数的默认值都可以修改

        this.apiInfo = ApiInfo.DEFAULT;
        this.groupName = "default";
        this.enabled = true;
        this.genericsNamingStrategy = new DefaultGenericTypeNamingStrategy();
        this.applyDefaultResponseMessages = true;
        this.host = "";
        this.pathMapping = Optional.absent();
        this.apiSelector = ApiSelector.DEFAULT;
        this.enableUrlTemplating = false;
        this.vendorExtensions = Lists.newArrayList();

4. 分析源码

  • 自定义apiInfo

在这里插入图片描述

  • 根据源码自定义 apiInfo(apiInfo())
@Configuration
@EnableSwagger2
public class HelloSwagger {
    
    

    @Bean
    public Docket docket(){
    
    
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo());
    }
    private ApiInfo apiInfo(){
    
    
        return new ApiInfo("乾坤大挪移",
                "Api Documentation by qk",
                "9.9", "https://blog.csdn.net/qq_40429067",
                new Contact("qk", "https://blog.csdn.net/qq_40429067", "[email protected]"),
                "Apache 2.0",
                "http://www.apache.org/licenses/LICENSE-2.0", new ArrayList());

    }

在这里插入图片描述

配置扫描接口

构建Docket时通过select()方法配置怎么扫描接口

@Bean
    public Docket docket(){
    
    
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                //.select()和.build()必须同时存在,否则会报错,再在中间.apis或.paths(),选择扫描的方式
                //RequestHandlerSelectors : 配置要扫描接口的方式
                         //basePackage : 指定要扫描的包
                         //any() : 扫描所有,项目中的所有接口都会被扫描到
                         //none() : 不扫描接口
                         //withMethodAnnotation() : 通过方法上的注解扫描,如:withMethodAnnotation(GetMapping.class)只扫描get请求
                         //withClassAnnotation() : 通过类上的注解扫描,如:withClassAnnotation(Controller.class)只扫描有controller注解的类中的接口
                         //basePackage() : 如:basePackage("com.qk.controller")只扫描com.qk.controller包下的接口
                .apis(RequestHandlerSelectors.basePackage("com.qk.controller"))
                //paths() :过滤什么路径,如:paths(PathSelectors.ant("/qk/**")),结合apis的扫描包的条件,扫描controller包下的带有"/qk/**"请求的接口
                        //any()   任何请求都扫描
                        //none()  任何请求都不扫描
                        //regex(final String pathRegex)  通过正则表达式控制
                        //ant(final String antPattern)  通过ant()控制
                .paths(PathSelectors.ant("/qk/**"))
                .build();
    }
  • 一个完整的配置扫描接口:扫描controller包下的带有"/qk/**"请求的接口
@Bean
    public Docket docket(){
    
    
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.qk.controller"))
                .paths(PathSelectors.ant("/t1/**"))
                .build();
    }

在这里插入图片描述

配置Swagger开关

  • .select()、.apis()和.build() 是一套的,必须紧密相连,其他配置在它们上面配置,path()可有可无
    在这里插入图片描述
@Bean
    public Docket docket(){
    
    
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .enable(false)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.qk.controller"))
                .build();
    }

通过enable()方法配置是否启用swagger,如果是false,swagger-ui.html将不能在浏览器中访问

在这里插入图片描述

根据当前运行的配置环境,决定是否开启swagger。如:开发环境下开启swagger,生产环境下不开启。

  • 通过Docket(Environment)中的Environment获取配置文件中当前激活的环境
@Bean
    public Docket docket(Environment environment){
    
    
        // 设置要显示swagger的环境,可以设置多个,只要满足一个返回值就为true,开启swagger
        Profiles of = Profiles.of("dev", "pro");
        // acceptsProfiles()需要一个Profiles类型的参数,所以在上面创建一个,而Profiles返回一个字符串数组,就是指定开启swagger的环境
        boolean isEnable = environment.acceptsProfiles(of);
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                // 通过 enable() 接收此参数判断是否要显示
                .enable(isEnable)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.qk.controller"))
                .paths(PathSelectors.ant("/hello/**"))
                .build();
    }
    private ApiInfo apiInfo(){
    
    
        return new ApiInfo("乾坤大挪移",
                "Api Documentation by qk",
                "9.9", "https://blog.csdn.net/qq_40429067",
                new Contact("qk", "https://blog.csdn.net/qq_40429067", "[email protected]"),
                "Apache 2.0",
                "http://www.apache.org/licenses/LICENSE-2.0", new ArrayList());

    }

在这里插入图片描述


swagger配置中,值的传递

在这里插入图片描述


配置API分组

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

1. 如果没有配置分组,默认是default。通过groupName()方法即可配置分组

2. 配置多个分组:在协同开发中,无论几个人,有多少个配置类,多少个Docket实例,都会被@Bean注入到容器中,在swagger中通过groupName进行分组

@Configuration
@EnableSwagger2
public class HelloSwagger {
    
    
    @Bean
    public Docket docket1(){
    
    
        return new Docket(DocumentationType.SWAGGER_2).groupName("group1");
    }
    @Bean
    public Docket docket2(){
    
    
        return new Docket(DocumentationType.SWAGGER_2).groupName("group2");
    }
    @Bean
    public Docket docket3(){
    
    
        return new Docket(DocumentationType.SWAGGER_2).groupName("group3");
    }
    @Bean
    public Docket docket(){
    
    
        return new Docket(DocumentationType.SWAGGER_2).groupName("default");
    }
}

在这里插入图片描述

实体配置

  1. 实体类
public class User {
    
    
    public String username;
    public String password;
}
  1. controller接口
@GetMapping("/user")
    public User user(){
    
    
        return new User();
    }
  1. 只要在接口中,返回值存在实体类,就会被扫描到swagger中

在这里插入图片描述

通过在实体类添加注解,提高swagger的models的可读性

  • @ApiModel为类添加注释
  • @ApiModelProperty为类属性添加注释
@ApiModel("用户实体类")
public class User {
    
    
    @ApiModelProperty("用户名")
    public String username;
    @ApiModelProperty("密码")
    public String password;
}

在这里插入图片描述

  • 只要接口的返回值为实体,都会被映射到models中,@ApiModel和@ApiModelProperty这两个注解只是为实体添加注释的,与是否显示在models中无关

通过@ApiOperation注解为接口的方法添加注释

@RestController
public class MyController {
    
    
    @ApiOperation("hello控制类")
    @PostMapping("/t1")
    public String test01(){
    
    
        return "hello swagger";
    }

    @GetMapping("/user")
    public User user(){
    
    
        return new User();
    }
}

在这里插入图片描述

通过@ApiParam注解为接口的方法参数添加注释

    @GetMapping("/user")
    public User user(@ApiParam("用户名") String username){
    
    
        return new User();
    }

在这里插入图片描述

在swagger中测试接口

  1. 没有参数的
@ApiOperation("hello控制类")
    @PostMapping("/t1")
    public String test01(){
    
    
        return "hello swagger";
    }

在这里插入图片描述

  1. 参数类型为实体的
@PostMapping("/user1")
    public String test03(User user){
    
    
        return user.getUsername()+"的swagger测试成功";
    }

在这里插入图片描述

  1. 其他测试:非对象型参数的传递,后端和swagger始终为null,目前没有找到解决方法
@PostMapping("/user")
    public String test02(@ApiParam("用户名") String username,@ApiParam("密码") String password){
    
    
        System.out.println(username+"被成功接收");
        return username+"的密码是"+password;
    }

在这里插入图片描述

总结:

  • 可以通过swagger给一些比较难理解的属性或者接口,增加注释信息
  • 接口文档实时更新
  • 可以在线测试

拓展:其他皮肤

导入不同的jar包实现不同的皮肤定义:

1、默认的 访问 http://localhost:8080/swagger-ui.html

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

2、bootstrap-ui 访问 http://localhost:8080/doc.html

<dependency>
   <groupId>com.github.xiaoymin</groupId>
   <artifactId>swagger-bootstrap-ui</artifactId>
   <version>1.9.1</version>
</dependency>

3、Layui-ui 访问 http://localhost:8080/docs.html

<dependency>
   <groupId>com.github.caspar-chen</groupId>
   <artifactId>swagger-ui-layer</artifactId>
   <version>1.1.3</version>
</dependency>

4、mg-ui 访问 http://localhost:8080/document.html

<dependency>
   <groupId>com.zyplayer</groupId>
   <artifactId>swagger-mg-ui</artifactId>
   <version>1.0.6</version>
</dependency>

猜你喜欢

转载自blog.csdn.net/qq_40429067/article/details/113778816