• springboot 集成 Swagger2(速通)


    1. 概述

    简单理解——代写接口文档的框架,可跟随接口修改实时更新。

    Open API 格式:REST API 的描述格式,可使用 YAML 或 JSON 格式来编写。Open API 的描述范围:

    • 每个访问地址的类型;
    • 每个操作的参数;
    • 认证方法;
    • 连接信息、声明,使用团队和其他信息。

    Swagger :一套围绕 Open API 规范构建的一款 RESTful 接口的文档在线自动生成和功能测试 API。将相关信息通过 YAML/JSON 格式存储在描述文件中,再通过描述文件去更新接口文档。其工具组包:

    • Swagger Editor:基于浏览器编辑器,可以编写 Open API 规范;
    • Swagger UI:将 Open API 规范呈现为交互式 API 文档,即描述文件(常用);
    • Swagger Codegen:将描述文件生成 HTML 和 cwiki 形式的接口文档,可同时生成多种语言的客户端和服务端代码;
    • Swagger Inspector:类似 Swagger UI,但包含更多信息,比如请求的实际参数数据;
    • Swagger Hub:集成上面工具的所有功能,上传描述文件到 Hub ,就可以完成上面工具的所有工作。

    Springfox:Swagger 在遇到版本迭代的时候还需要更改描述文件,但 Springfox 则优化了此过程,会根据代码实时生成文档。通过注解的方式将 Swagger 集成在代码中。

    2. 案例 1

    依赖:

    • web 项目

              <dependency>
                  <groupId>org.springframework.bootgroupId>
                  <artifactId>spring-boot-starter-webartifactId>
              dependency>
      
      • 1
      • 2
      • 3
      • 4
    • springfox 依赖,要一次性导入下面两个,版本要对应

              <dependency>
                  <groupId>io.springfoxgroupId>
                  <artifactId>springfox-swagger2artifactId>
                  <version>2.9.2<version>
              dependency>
              <dependency>
                  <groupId>io.springfoxgroupId>
                  <artifactId>springfox-swagger-uiartifactId>
                  <version>2.9.2<version>
              dependency>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10

    注解:

    • 启动类注解:

      @EnableSwagger2         // 开启 swagger2 相关技术,扫描当前类所在包及其子包中的注解 
      @SpringBootApplication
      
      • 1
      • 2
    • 控制类:

      @RestController
      public class SwaggerController {
          @GetMapping("/get")
          public String getStr(String str) {
              return "SELECT " + str;
          }
      
          @PostMapping("/post")
          public String postStr(String str) {
              return "CREATE " + str;
          }
      
          @PutMapping("/put")
          public String putStr(String str) {
              return "UPDATE " + str;
          }
      
          @PatchMapping("/patch")
          public String patchStr(String str) {
              return "UPDATE " + str;
          }
          
          @DeleteMapping("/delete")
          public String deleteStr(String str) {
              return "DELETE " + str;
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
    • 运行代码,访问 http://127.0.0.1:8080/swagger-ui.html,这里可能会遇到以下的报错:

      启动项目遇到报错:java: 警告: 源发行版 17 需要目标发行版 17
      解决方案:https://blog.csdn.net/weixin_44299027/article/details/120848738


      启动项目遇到报错:类文件具有错误的版本 61.0, 应为 52.0
      解决方案:spring6.0 开始 jdk 要求17以上才行,要么升级 JDK,要么降低 spring 版本。
      我选择降低 spring 版本:

      • https://mvnrepository.com/ 查看 spring-boot-starter-parent 的版本号
      • 选择 3 以下的版本号,修改 Maven 依赖 spring-boot-starter-parent


      启动项目遇到报错:Failed to start bean ‘documentationPluginsBootstrapper’;
      解决方案:springboot 升级到 2.6.0之后,swagger版本和springboot出现了不兼容情况,要么降低 springboot 版本,要么配置 spring.mvc.pathmatch.matching-strategy=ant_path_matcher

      • A.降低 springboot 版本不再做赘述(可降低至 2.5 以下就绝对没问题);
      • B.配置1:① 启动类加上注解 @EnableWebMvc;② 配置文件加上 spring.mvc.pathmatch.matching-strategy=ant_path_matcher;
      • C.配置1不生效情况:参考:https://blog.csdn.net/weixin_39792935/article/details/122215625
      • D.当上述三种解决方案都不生效的情况下,我采用的终极解决方案:降低 Springboot 版本(2.5.6),并采用 C 方案的配置,然后访问 http://127.0.0.1:8080/swagger-ui.html

        访问页面为空:

        解决方案:启动类加上注解@EnableOpenApi ,并访问 http://localhost:8080/swagger-ui/index.html
    • 解决无法访问的问题:

      • 修改配置文件 application.properties

        spring.mvc.pathmatch.matching-strategy=ant_path_matcher
        
        • 1
      • 新增配置类:

        package com.chenjy.swagger.config;
        
        import org.springframework.context.annotation.Configuration;
        import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
        import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
        
        /**
         * @Desc 解决高版本无法兼容 swagger2 的问题
         *       如此配置之后,就可通过 http://127.0.0.1:8080/doc.html 去访问 swagger-ui.html
         */
        @Configuration
        public class WebMvcConfigurer extends WebMvcConfigurationSupport {
        
            /**
             * 发现如果继承了WebMvcConfigurationSupport,则在yml中配置的相关内容会失效。 需要重新指定静态资源
             */
            @Override
            public void addResourceHandlers(ResourceHandlerRegistry registry) {
                registry.addResourceHandler("/**").addResourceLocations(
                        "classpath:/static/");
                registry.addResourceHandler("swagger-ui.html", "doc.html").addResourceLocations(
                        "classpath:/META-INF/resources/");
                registry.addResourceHandler("/webjars/**").addResourceLocations(
                        "classpath:/META-INF/resources/webjars/");
                super.addResourceHandlers(registry);
            }
        
        }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
        • 18
        • 19
        • 20
        • 21
        • 22
        • 23
        • 24
        • 25
        • 26
        • 27
        • 28
      • 降低 springboot 版本到 2.5.6

            <parent>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-parentartifactId>
                <version>2.5.6version>
                <relativePath/> 
            parent>
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
    • 访问界面如下图,可以从中看到我们写的接口:

    3. UI 的简单使用

    扫描项目中(启动类同级目录及其子目录中)的所有控制器(默认是控制器) 中的 @GetMapping/@RequestMapping(method = {RequestMethod.GET}) 系列的注解,然后去解析注解对应的映射地址以及注解约束的请求方式(GET、POST、DELET…,默认为 GET)。点击具体方法可看详细的请求信息:

    可点击 Try it out 测试一下:

    4. 简单配置 Docket 对象

    1. 配置文档的描述信息

    package com.chenjy.swagger.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import springfox.documentation.builders.ApiInfoBuilder;
    import springfox.documentation.service.ApiInfo;
    import springfox.documentation.service.Contact;
    import springfox.documentation.spi.DocumentationType;
    import springfox.documentation.spring.web.plugins.Docket;
    
    @Configuration
    public class SwaggerConfigurer {
    
        /**
         * @return Docket——Swagger 中的全局配置对象
         */
        @Bean
        public Docket docket() {
            // DocumentationType.SWAGGER_2 告诉 Springfox 当前的 Swagger 版本是 Swagger2
            Docket docket = new Docket(DocumentationType.SWAGGER_2);
            // API 帮助文档的描述信息
            ApiInfo apiInfo = new ApiInfoBuilder()
                    .title("Swagger 文档")// 文档标题
                    .description("Swagger :一套围绕 Open API 规范构建的一款 RESTful 接口的文档在线自动生成和功能测试 API。")// 描述信息
                    .version("1.0.1")// 版本号
                    .contact(
                            // name url email
                            new Contact("364.99°的文档", // 文档发布者名称
                                    "https://blog.csdn.net/m0_54355172", // 文档发布者的网站地址
                                    "2190826197@qq.com" // 文档发布者的邮箱
                            )
                    )
                    // 构建器模式
                    .build();
            // 给 docket 上下文配置 API 描述信息
            docket.apiInfo(apiInfo);
            return docket;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    2. 定义包扫描规则

    在 docket 方法中添加以下配置:

            docket
                    .select() // 获取 docket 中的选择器,如:扫描哪个包的注解
                    .apis(RequestHandlerSelectors.basePackage("com.chenjy.swagger.controller")); // 定义规则——包扫描规则
    
    • 1
    • 2
    • 3

    5. 指定接口不生成文档

    1. 自定义注解

    如何自定义一个注解

    定义一个注解,标注当前接口不需要生成 Swagger 文档:

    package com.chenjy.swagger.annotation;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Target({ElementType.METHOD, ElementType.TYPE}) // 此注解用于描述 方法、类
    @Retention(RetentionPolicy.RUNTIME)// 注释信息会在运行时被有效
    public @interface NoSwagger {
        // 自定义注解属性 @NoSwagger(value="")
        String value() default "";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    配置类使注解规则生效:

    package com.chenjy.swagger.config;
    
    import com.chenjy.swagger.annotation.NoSwagger;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import springfox.documentation.builders.ApiInfoBuilder;
    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 static com.google.common.base.Predicates.not;
    import static springfox.documentation.builders.RequestHandlerSelectors.withMethodAnnotation;
    
    @Configuration
    public class SwaggerConfigurer {
    
        /**
         * @return Docket——Swagger 中的全局配置对象
         */
        @Bean
        public Docket docket() {
            // DocumentationType.SWAGGER_2 告诉 Springfox 当前的 Swagger 版本是 Swagger2
            Docket docket = new Docket(DocumentationType.SWAGGER_2);
            // API 帮助文档的描述信息
            ApiInfo apiInfo = new ApiInfoBuilder()
                    .title("Swagger 文档")// 文档标题
                    .description("Swagger :一套围绕 Open API 规范构建的一款 RESTful 接口的文档在线自动生成和功能测试 API。")// 描述信息
                    .version("1.0.1")// 版本号
                    .contact(
                            // name url email
                            new Contact("364.99°的文档", // 文档发布者名称
                                    "https://blog.csdn.net/m0_54355172", // 文档发布者的网站地址
                                    "2190826197@qq.com" // 文档发布者的邮箱
                            )
                    )
                    // 构建器模式
                    .build();
            // 给 docket 上下文配置 API 描述信息
            docket.apiInfo(apiInfo);
            Docket build = docket
                    .select() // 获取 docket 中的选择器,如:扫描哪个包的注解
                    .apis(
                            not( // 取反
                                    withMethodAnnotation(NoSwagger.class) // 当方法上有注解的时候返回 true
                            )
                    )
                    .apis(RequestHandlerSelectors.basePackage("com.chenjy.swagger.controller")) // 定义规则——包扫描规则
                    .build();
            return build;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    注意: 这里需要重新 build 一次 Docket ,然后返回重新 build 之后的 docket,否则不会生效。

    标注在接口方法上:

        @NoSwagger
        @PatchMapping("/patch")
        public String patchStr(String str) {
            return "UPDATE " + str;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    重启项目,访问:

    优化写法:

            Docket build = docket
                    .select() // 获取 docket 中的选择器,如:扫描哪个包的注解
                    .apis(
                            and(
                                    not( // 取反
                                            withMethodAnnotation(NoSwagger.class) // 当方法上有注解的时候返回 true
                                    ),
                                    RequestHandlerSelectors.basePackage("com.chenjy.swagger.controller")
                            )
                    )
                    .build();
            return build;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    注意:

    • andnot 都是 com.google.common.base.Predicates 中的静态方法;
    • withMethodAnnotationspringfox.documentation.builders.RequestHandlerSelectors 中的静态方法。

    2. 路径匹配

    springfox.documentation.builders.PathSelectors

    只有路径前缀为 /test 的接口方法才会生成文档。

            Docket build = docket
                    .select() // 获取 docket 中的选择器,如:扫描哪个包的注解
                    .paths(
                            PathSelectors.regex("/test/.*") // 使用正则表达式  . 任意字符   * 0个或多个
                    )
                    .build();
            return build;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    同时多种路径匹配规则: Predicates.or

                    .paths(
                            Predicates.or(
                                    PathSelectors.regex("/test/.*"),
                                    PathSelectors.regex("/.*")
                            )
                    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    → 正则表达式语法 ←

    6. 常用注解

    @Api(tags = {"test 接口 API"})

    • 类注解,描述当前类型生成帮助文档的信息;
    • tags 定义控制器别名,可以有多个值,有几个别名,文档中就有几个控制器目录。

    @ApiOperation(value = "get 方法,执行查询操作", notes = "一个小 demo")

    • 类、方法注解,常用来描述方法。

    @ApiParam()

    • 参数、方法、属性注解,常用来描述参数;

      @PostMapping("/post")
      public String postStr(
              @ApiParam(name = "字符串", value = "用来输出的字符串", required = true) String str,
              @ApiParam(name = "序列号", required = false) @RequestParam(defaultValue = "001", required = false)String num
      ) {
          return "CREATE " + str + num;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7

    @ApiIgnore

    • 方法、属性注解,让此注解描述的方法或类型不生成 API 文档。

          @ApiIgnore
          @PutMapping("/put")
          public String putStr(String str) {
              return "UPDATE " + str;
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5

    @ApiImplicitParam

    • 在方法上描述方法参数,只能描述一个参数。

          @ApiImplicitParam(
                  name = "str", value = "一个字符串", required = true, paramType = "java.lang.String", dataType = "任意字符串"
          )
          @DeleteMapping("/delete")
          public String deleteStr(String str, Integer num) {
              return "DELETE " + str;
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7

    ApiImplicitParams

    • 在方法上描述参数,可以描述多个参数。
          @ApiImplicitParams(value = {
                 @ApiImplicitParam( name = "str", value = "一个字符串", required = true, paramType = "java.lang.String", dataType = "任意字符串" ),
                 @ApiImplicitParam( name = "num", value = "一个整数") 
          })
          @DeleteMapping("/delete")
          public String deleteStr(String str, Integer num) {
              return "DELETE " + str;
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8

    @ApiModel

    • 描述实体类,当此实体类被作为返回类型用于 API 帮助文档中的接口方法中,此注解被解析。

      @Data
      @NoArgsConstructor
      @AllArgsConstructor
      @ApiModel( value = "一个实体类", description = "存储数据并返回")
      public class TestDto {
          private String name;
          private Integer num;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
          @PatchMapping("/patch")
          public TestDto patchStr(String str, Integer num) {
              return new TestDto(str, num);
          }
      
      • 1
      • 2
      • 3
      • 4

    @ApiModelProperty

    • 描述实体类的属性,要搭配 @ApiModel 使用。

      @Data
      @NoArgsConstructor
      @AllArgsConstructor
      @ApiModel( value = "一个实体类", description = "存储数据并返回")
      public class TestDto {
          @ApiModelProperty( value = "姓名", example = "张三", hidden = false)
          private String name;
          @ApiModelProperty( value = "序列号")
          private Integer num;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10


    注意:

    • GET:不能使用 @requestBody
    • POST:可以使用 @requestBody (对于参数转化的配置必须统一)和 @requestParam
  • 相关阅读:
    Misc | bucket 第二届“奇安信”杯网络安全技能竞赛
    html_语义化标签
    工作中常见的两种谬误
    齐岳|近红外染料CY7.5标记PCL聚已内酯纳米载体CY7.5-PCL|PCL-CY7.5|CY7.5-PEG-PCL
    【计算机网络期末复习】选择题①1~50
    strongswan:configure: error: OpenSSL Crypto library not found
    自动化测试报告
    图像分割 - 分水岭算法
    MindSponge分子动力学模拟——定义Collective Variables(2024.02)
    LeetCode 414. Third Maximum Number【数组】简单
  • 原文地址:https://blog.csdn.net/m0_54355172/article/details/130839916