一、什么是Swagger

Swagger

  • 号称世界上最流行的API框架
  • Restful Api 文档在线自动生成器 => API 文档 与API 定义同步更新
  • 直接运行,在线测试API
  • 支持多种语言 (如:Java,PHP等)
  • 官网:https://swagger.io/

它的出现是为了解决前后端联调的问题,实时更新跟踪API,降低集成风险

二、构建Swagger框架

  • 创建一个普通的springboot-web项目

  • 导入依赖

          <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
            <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>
    
    
  • 配置SwaggerConfig

    由于Swagger没有被springboot集成 所以我们需要自己配置一个javaconfig

    package com.llf.config;
    
    import io.swagger.models.Path;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.env.Environment;
    import org.springframework.core.env.Profiles;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    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;
    
    import java.util.ArrayList;
    
    @Configuration
    @EnableSwagger2
    public class SwaggerConfig {
        //配置Swagger的bean实例
        @Bean
         public Docket docket(Environment environment){
     
             return  new Docket(DocumentationType.SWAGGER_2)
        
    
        }
    
    }
    
    

@Configration: 表明这个类为springboot的配置类

@EnableSwagger2: 打开Swagger支持

@Bean 这个方法注册到springboot中

这样一个简单的Swagger框架就算搭建好了

三、访问Swagger-ui.html

在这里插入图片描述

通过访问http://localhost:8081/swagger-ui.html 我们可以看出 整个ui界面由四个部分组成

  • API Documentation
  • Controller模块
  • Models实体类模块
  • Group 分组模块

而这些模块的信息都是默认的 我们可以根据自己的需求来改变这些信息

四、修改API Documentation

在这里插入图片描述

  • 通过查看原码 我们知道apiInfo()方法需要一个apiinfo参数 于是我们创建一个
   private ApiInfo apiInfo(){
       
   }
  • 继续看 我们知道apiinfo返回的是一个apiinfo对象

!在这里插入图片描述](https://img-blog.csdnimg.cn/b15e81f493f149098a80d91dfbcfc8f0.png)在这里插入图片描述

return  new ApiInfo("Api Documentation",
                    "Api Documentation", "1.0",
                    "urn:tos",
                    DEFAULT_CONTACT,
                    "Apache 2.0", "http://www.apache.org/licenses/LICENSE-2.0",
                    new ArrayList());
    }
  • 然后发现DEFAULT_CONTACT报错 继续看我们发现DEFAULT_CONTACT也是一个对象 于是我们继续创建它并引用

在这里插入图片描述

 private ApiInfo apiInfo(){
        //配置作者信息
        Contact DEFAULT_CONTACT
                = new Contact("llf", "www.baidu.com", "1471305491@QQ.com");
  • 最后变成下面的
package com.llf.config;

import io.swagger.models.Path;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
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;

import java.util.ArrayList;

@Configuration
@EnableSwagger2
public class SwaggerConfig {
    //配置Swagger的bean实例
    @Bean
     public Docket docket(){

         return  new Docket(DocumentationType.SWAGGER_2)
                 .apiInfo(apiInfo()) 

     }


     //配置swagger信息 apiInfo
    private ApiInfo apiInfo(){
        //配置作者信息
        Contact DEFAULT_CONTACT
                = new Contact("llf", "www.baidu.com", "1471305491@QQ.com");
       return   new ApiInfo("飞哥的SwaggerAPI文档",
               "我要学习啦",
               "V1.0",
               "http://localhost:8080/",
               DEFAULT_CONTACT,
               "Apache 2.0",
               "http://www.apache.org/licenses/LICENSE-2.0",
               new ArrayList());

    }
  
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-meiwZLR2-1627023202675)(C:\Users\machenike\AppData\Roaming\Typora\typora-user-images\image-20210723140933030.png)]

不同的参数对应不同的内容

五、自定义Swagger-Controller

使用select方法+build方法

                 .select()
                 /*
                 配置扫描接口的方式
                  1、扫描方法上注解为GetMapping的请求
                  .apis(RequestHandlerSelectors.withMethodAnnotation(GetMapping.class))
                  2、扫描类上为Controller的所有类中的请求
                 .apis(RequestHandlerSelectors.withClassAnnotation(Controller.class))
                 3、什么也不扫描
                 .apis(RequestHandlerSelectors.none())
                 4、扫描所有请求
                  .apis(RequestHandlerSelectors.any())
                  */
                 // 只扫描com.llf.controller包下的请求
                .apis(RequestHandlerSelectors.basePackage("com.llf.controller"))
                // paths  过滤请求
                 /*
                 .paths(PathSelectors.any() 扫描所有请求
                 .paths(PathSelectors.none()什么都不扫描
                 .paths(PathSelectors.ant("/llf/**"))    
                 只扫描com.llf.controller包下的请求的/llf/**路径下的所有请求

                 可配可不配
                  */
                // .paths(PathSelectors.ant("/llf/**"))
                 .build();

使用.apis(RequestHandlerSelectors.xxx())方法 来指定扫描哪一个包下的文件

package com.llf.config;

import io.swagger.models.Path;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
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;

import java.util.ArrayList;

@Configuration
@EnableSwagger2
public class SwaggerConfig {
    //配置Swagger的bean实例
    @Bean
     public Docket docket(Environment environment){
         return  new Docket(DocumentationType.SWAGGER_2)
                 .apiInfo(apiInfo())
                 .select()
                 /*
                 配置扫描接口的方式
                  1、扫描方法上注解为GetMapping的请求
                  .apis(RequestHandlerSelectors.withMethodAnnotation(GetMapping.class))
                  2、扫描类上为Controller的所有类中的请求
                 .apis(RequestHandlerSelectors.withClassAnnotation(Controller.class))
                 3、什么也不扫描
                 .apis(RequestHandlerSelectors.none())
                 4、扫描所有请求
                  .apis(RequestHandlerSelectors.any())
                  */
                 // 只扫描com.llf.controller包下的请求
                .apis(RequestHandlerSelectors.basePackage("com.llf.controller"))
                // paths  过滤请求
                 /*
                 .paths(PathSelectors.any() 扫描所有请求
                 .paths(PathSelectors.none()什么都不扫描
                 .paths(PathSelectors.ant("/llf/**"))    只扫描/llf/**路径下的所有请求

                 可配可不配
                  */
                // .paths(PathSelectors.ant("/llf/**"))
                 .build();
     }


     //配置swagger信息 apiInfo
    private ApiInfo apiInfo(){
        //配置作者信息
        Contact DEFAULT_CONTACT
                = new Contact("llf", "www.baidu.com", "1471305491@QQ.com");
       return   new ApiInfo("飞哥的SwaggerAPI文档",
               "我要学习啦",
               "V1.0",
               "http://localhost:8080/",
               DEFAULT_CONTACT,
               "Apache 2.0",
               "http://www.apache.org/licenses/LICENSE-2.0",
               new ArrayList());

    }

}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KfbjZcpN-1627023202676)(C:\Users\machenike\AppData\Roaming\Typora\typora-user-images\image-20210723141651208.png)]

我们可以看出 它已经成功访问了controller包下的所有请求

六、扫描Model实体类

  • 首先我们要准备一个实体类 并给其准备get、set、构造器等方法

  • 其次 只要我们请求的返回值中有实体类 那么实体类就会被扫描到

    ​ 于是我们编写一个Controller请求 使其返回一个实体类

   @PostMapping("/user")
    public User user(){
        return user();
    }
  • 再次访问

在这里插入图片描述

它已经成功扫描到了实体类

现在想 如果 如果我们有很多参数 而有的参数前端的人看不懂怎么办?

于是我们用到了API注解 我们可以通过在属性上添加API注解的方式 来解释整个属性

    @ApiModelProperty("账号")
    private  String username;
    @ApiModelProperty("密码")
    private  String password;

在这里插入图片描述

这样就完美解决了我们的问题

七、根据运行环境切换Swagger

在正常的开发中,我们只有在测试、开发的过程中用到Swagger,一旦产品上线,我们是必须要关闭Swagger的,如果开启,用户会通过Swagger-ui.html访问到后台,从而导致接口数据的暴露

  • 如何关闭Swagger

    .enable()
    

这个方法默认值是true 只要我们填入false Swagger就会关闭

知道了怎么关闭 我们的思路就清晰了 我们可以获取当前运行环境,然后与Swagger中允许运行的环境作比较 得到一个布尔值 再赋给.enable()

  • 如何获取当前环境
    • 给Docket方法 添加Environment environment参数
 @Bean
     public Docket docket(Environment environment){
     

通过Profiles.of方法设置允许运行的环境

        //设置Swagger要显示的环境
        Profiles profiles= Profiles.of("dev","test");

通过environment.acceptsProfiles(profiles)方法获取当前运行环境并进行判断 是否符合要求

       boolean flag = environment.acceptsProfiles(profiles);

将布尔值flag赋给.enable() 完成设置

  .enable(flag)
package com.llf.config;

import io.swagger.models.Path;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
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;

import java.util.ArrayList;

@Configuration
@EnableSwagger2
public class SwaggerConfig {
    //配置Swagger的bean实例
    @Bean
     public Docket docket(Environment environment){

        //设置Swagger要显示的环境
        Profiles profiles= Profiles.of("dev","test");

       //判断运行的环境是不是想要设置的Swagger环境
        boolean flag = environment.acceptsProfiles(profiles);
        //获取项目运行的环境
        environment.getActiveProfiles();
         return  new Docket(DocumentationType.SWAGGER_2)
                 .apiInfo(apiInfo())
                 //是否启动配置 默认为true
                 .enable(flag)
                 .select()
                 /*
                 配置扫描接口的方式
                  1、扫描方法上注解为GetMapping的请求
                  .apis(RequestHandlerSelectors.withMethodAnnotation(GetMapping.class))
                  2、扫描类上为Controller的所有类中的请求
                 .apis(RequestHandlerSelectors.withClassAnnotation(Controller.class))
                 3、什么也不扫描
                 .apis(RequestHandlerSelectors.none())
                 4、扫描所有请求
                  .apis(RequestHandlerSelectors.any())
                  */
                 // 只扫描com.llf.controller包下的请求
                .apis(RequestHandlerSelectors.basePackage("com.llf.controller"))
                // paths  过滤请求
                 /*
                 .paths(PathSelectors.any() 扫描所有请求
                 .paths(PathSelectors.none()什么都不扫描
                 .paths(PathSelectors.ant("/llf/**"))    只扫描/llf/**路径下的所有请求

                 可配可不配
                  */
                // .paths(PathSelectors.ant("/llf/**"))
                 .build();
     }


     //配置swagger信息 apiInfo
    private ApiInfo apiInfo(){
        //配置作者信息
        Contact DEFAULT_CONTACT
                = new Contact("llf", "www.baidu.com", "1471305491@QQ.com");
       return   new ApiInfo("飞哥的SwaggerAPI文档",
               "我要学习啦",
               "V1.0",
               "http://localhost:8080/",
               DEFAULT_CONTACT,
               "Apache 2.0",
               "http://www.apache.org/licenses/LICENSE-2.0",
               new ArrayList());

    }

}

在这里插入图片描述

环境错误就会进不去页面 只有环境对了才能正常进入

在这里插入图片描述

八、管理分组

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5Qd0WzqE-1627023202679)(C:\Users\machenike\AppData\Roaming\Typora\typora-user-images\image-20210723144652215.png)]

默认的组别只有一个default 我们可以通过.groupName("xx")方法来自定义我们的名称

.groupName("飞哥")

增加分组 就是多创建几个Docket方法 并通过.groupName("xx")方法定义名字即可

 @Bean
    public Docket docket1(){
        return  new Docket(DocumentationType.SWAGGER_2).groupName("飞弟");
    }
    @Bean
    public Docket docket2(){
        return  new Docket(DocumentationType.SWAGGER_2).groupName("飞姐");
    }

访问

在这里插入图片描述

每个人都有每个人的页面,根据不同的设置显示出来,提高开发效率

总结

Swagger是个优秀的工具,现在国内已经有很多的中小型互联网公司都在使用它,相较于传统的要先出Word接口文档再测试的方式,显然这样也更符合现在的快速迭代开发行情。当然了,提醒下大家在正式环境要记得关闭Swagger,一来出于安全考虑二来也可以节省运行时内存。

**Swagger全部代码**

package com.llf.config;

import io.swagger.models.Path;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
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;

import java.util.ArrayList;

@Configuration
@EnableSwagger2
public class SwaggerConfig {
    //配置Swagger的bean实例
    @Bean
     public Docket docket(Environment environment){

        //设置Swagger要显示的环境
        Profiles profiles= Profiles.of("dev");


       //判断运行的环境是不是想要设置的Swagger环境
        boolean flag = environment.acceptsProfiles(profiles);

         return  new Docket(DocumentationType.SWAGGER_2)
                 .apiInfo(apiInfo())
                 //是否启动配置 默认为true
                 .enable(flag)
                 .groupName("飞哥")
                 .select()
                 /*
                 配置扫描接口的方式
                  1、扫描方法上注解为GetMapping的请求
                  .apis(RequestHandlerSelectors.withMethodAnnotation(GetMapping.class))
                  2、扫描类上为Controller的所有类中的请求
                 .apis(RequestHandlerSelectors.withClassAnnotation(Controller.class))
                 3、什么也不扫描
                 .apis(RequestHandlerSelectors.none())
                 4、扫描所有请求
                  .apis(RequestHandlerSelectors.any())
                  */
                 // 只扫描com.llf.controller包下的请求
                .apis(RequestHandlerSelectors.basePackage("com.llf.controller"))
                // paths  过滤请求
                 /*
                 .paths(PathSelectors.any() 扫描所有请求
                 .paths(PathSelectors.none()什么都不扫描
                 .paths(PathSelectors.ant("/llf/**"))    只扫描/llf/**路径下的所有请求

                 可配可不配
                  */
                // .paths(PathSelectors.ant("/llf/**"))
                 .build();
     }


     //配置swagger信息 apiInfo
    private ApiInfo apiInfo(){
        //配置作者信息
        Contact DEFAULT_CONTACT
                = new Contact("llf", "www.baidu.com", "1471305491@QQ.com");
       return   new ApiInfo("飞哥的SwaggerAPI文档",
               "我要学习啦",
               "V1.0",
               "http://localhost:8080/",
               DEFAULT_CONTACT,
               "Apache 2.0",
               "http://www.apache.org/licenses/LICENSE-2.0",
               new ArrayList());

    }
    @Bean
    public Docket docket1(){
        return  new Docket(DocumentationType.SWAGGER_2).groupName("飞弟");
    }
    @Bean
    public Docket docket2(){
        return  new Docket(DocumentationType.SWAGGER_2).groupName("飞姐");
    }
}

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐