SpringBoot3中Swagger整合knife4j和springdoc的配置说明
作者:mmseoamin日期:2023-12-25

 

springboot3开始javax包改成了jakarta,而swagger-oas等包中依然使用的是javax所以报错。另外springfox已经过时了,两年没更新了,并且不支持OpenAPI3 标准,而SpringBoot3只支持OpenAPI3规范,所以要迁移到springdoc

Knife4J是一款基于Swagger快速生成API文档和调试平台的开源工具,它可以轻松地将Swagger规范转换成易于阅读的文档,并支持在线测试API。Knife4J内置了多种主题和插件,提供了丰富的样式和功能配置,可以自定义API文档的展示方式和内容。

OpenAPI3的规范,目前针对Java的Spring Boot项目,主要支持的有2个版本
  • springfox 3.0.0: 同时兼容OpenAPI2以及OpenAPI3,但是停更很久了
  • springdoc-openapi:兼容OpenAPI3规范,更新速度频繁
    Knife4j在只有的OpenAPI3规范中,底层基础框架选择springdoc-openapi项目
    • 针对Springfox3.0.0版本会放弃。

       

      Spring Boot版本兼容性

      以下是一些常见的Spring Boot版本及其对应的Knife4j版本兼容推荐:

      Spring Boot版本Knife4j Swagger2规范Knife4j OpenAPI3规范
      1.5.x~2.0.0>=Knife4j 4.0.0
      2.0~2.2Knife4j 2.0.0 ~ 2.0.6>=Knife4j 4.0.0
      2.2.x~2.4.0Knife4j 2.0.6 ~ 2.0.9>=Knife4j 4.0.0
      2.4.0~2.7.x>=Knife4j 4.0.0>=Knife4j 4.0.0
      >= 3.0>=Knife4j 4.0.0>=Knife4j 4.0.0

      参考:knife4j官网 springdoc-openapi官网

      配置: JDK17 + SpringBoot:3.1.5 + knife4j:4.3.0 + springdoc2.2.0

       

      1.导入依赖(SpringBoot3)
       
      
          com.github.xiaoymin
          knife4j-openapi3-jakarta-spring-boot-starter
          4.3.0
      
      
      2.在application.yml中设置相关配置:
      #springdoc相关配置
      springdoc:
        swagger-ui:
          #自定义swagger前端请求路径,输入http:127.0.0.1:8080/swagger-ui.html会自动重定向到swagger页面
          path: /swagger-ui.html
          tags-sorter: alpha
          operations-sorter: alpha
        api-docs:
          path: /v3/api-docs    #swagger后端请求地址
          enabled: true   #是否开启文档功能
        group-configs:
          - group: 'com.hgh.yuzhan'
            paths-to-match: '/**'
            packages-to-scan: com.hgh.yuzhan    #按包路径匹配:一般到启动类的包名
      #knife4j相关配置 可以不用改
      knife4j:
        enable: true    #开启knife4j,无需添加@EnableKnife4j注解
        setting:
          language: zh_cn   #中文
          swagger-model-name: 实体类   #重命名SwaggerModel名称,默认
        #开启Swagger的Basic认证功能,默认是false
        basic:
          enable: true
          # Basic认证用户名
          username: hgh
          # Basic认证密码
          password: a1234567
      
      3.配置文件
      /**
       * @description: knife4j配置类
       * @authod:  GreyPigeon mail:2371849349@qq.com
       * @date:    2023/11/10 20:49
       **/
      @Configuration
      public class OpenApiConfig {
          @Bean
          public OpenAPI springShopOpenAPI() {
              return new OpenAPI()
                      // 接口文档标题
                      .info(new Info().title("愈站API接口文档")
                              // 接口文档简介
                              .description("这是基于Knife4j OpenApi3的接口文档")
                              // 接口文档版本
                              .version("v1.0")
                              // 开发者联系方式
                              .contact(new Contact().name("GrayPigeonHGH").email("2371849349@qq.com")))
                      .externalDocs(new ExternalDocumentation()
                              .description("SpringBoot基础框架")
                              .url("http://127.0.0.1:8088"));
          }
          //以下分组可省略
          @Bean
          public GroupedOpenApi systemApi() {
              return GroupedOpenApi.builder().group("System系统模块")
                      .pathsToMatch("/system/**")
                      .build();
          }
          @Bean
          public GroupedOpenApi authApi() {
              return GroupedOpenApi.builder().group("Auth权限模块")
                      .pathsToMatch("/captcha", "/login")
                      .build();
          }
      }
      

      参考:https://huaweicloud.csdn.net/63876baddacf622b8df8bb31.html

      • 注意:Knife4j 自4.0版本,下面的配置在knife4j-openapi2-spring-boot-starter中仍然需要如此配置,而在knife4j-openapi3-spring-boot-starter和knife4j-openapi3-jakarta-spring-boot-starter则不需要以下配置!!!
        @Configuration
        @EnableSwagger2WebMvc
        public class SwaggerConfiguration {
            /*引入Knife4j提供的扩展类*/
           private final OpenApiExtensionResolver openApiExtensionResolver;
            @Autowired
            public SwaggerConfiguration(OpenApiExtensionResolver openApiExtensionResolver) {
                this.openApiExtensionResolver = openApiExtensionResolver;
            }
        @Bean(value = "defaultApi2")
            public Docket defaultApi2() {
                String groupName="2.X版本";
                Docket docket=new Docket(DocumentationType.SWAGGER_2)
                        .host("https://www.baidu.com")
                        .apiInfo(apiInfo())
                        .groupName(groupName)
                        .select()
                        .apis(RequestHandlerSelectors.basePackage("com.swagger.bootstrap.ui.demo.new2"))
                        .paths(PathSelectors.any())
                        .build()
                        //赋予插件体系
                        .extensions(openApiExtensionResolver.buildExtensions(groupName));
                return docket;
            }
        
        4.访问路径

        swagger 接口文档默认地址:http://localhost:8080/swagger-ui.html#

        Knife4j 接口文档默认地址:http://127.0.0.1:8080/doc.html

        5. Springfox改用Springdoc后,注解改变:
        @Api → @Tag
        @ApiIgnore → @Parameter(hidden = true) or @Operation(hidden = true) or @Hidden
        @ApiImplicitParam → @Parameter
        @ApiImplicitParams → @Parameters
        @ApiModel → @Schema
        @ApiModelProperty(hidden = true) → @Schema(accessMode = READ_ONLY)
        @ApiModelProperty → @Schema
        @ApiOperation(value = "foo", notes = "bar") → @Operation(summary = "foo", description = "bar")
        @ApiParam → @Parameter
        @ApiResponse(code = 404, message = "foo") → @ApiResponse(responseCode = "404", description = "foo")
        
        6.以下举几个简单的例子:
        6.1 Controller:
        @Tag(name = "用户接口")
        @RestController
        @RequestMapping("sys/user")
        public class SysUserController {
            @Resource
            private ISysUserService sysUserService;
            @Operation(summary = "分页查询")
            @GetMapping("page")
            public AjaxResult queryPage(@ParameterObject SysUserPageDTO dto) {
                PageInfo page = sysUserService.queryPage(dto);
                return AjaxResult.success(page);
            }
            @Operation(summary = "详情")
            @GetMapping("{id}")
            public AjaxResult queryInfo(@PathVariable Long id) {
                SysUserDTO dto = sysUserService.queryById(id);
                return AjaxResult.success(dto);
            }
            @Operation(summary = "新增")
            @PostMapping
            public AjaxResult save(@RequestBody SysUserDTO dto) {
                Long id = sysUserService.saveInfo(dto);
                return AjaxResult.success(id);
            }
        }
        
        6.2 实体类
        @Getter
        @Setter
        @TableName("user")
        @Schema(name = "User", description = "$!{table.comment}")
        public class User implements Serializable {
            private static final long serialVersionUID = 1L;
            @Schema(description = "主键")
            @TableId("id")
            private Long id;
            @Schema(description = "用户名")
            @TableField("name")
            private String name;
            @Schema(description = "手机号")
            @TableField("phone")
            private String phone;
            @Schema(description = "性别")
            @TableField("sex")
            private String sex;
            @Schema(description = "状态 0:禁用,1:正常")
            @TableField("status")
            private Integer status;
        }