文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Spring Doc OpenAPI3.0 抛弃SpringFox拥抱SpringDoc

2023-09-22 16:14

关注

Spring Doc

1 简介

SpringDoc是SpringBoot 的API文档工具。官网:https://springdoc.org/

在使用SpringBoot 2.6以前去创建API文档工具一般会采用SpringFox提供的Swagger库,但是由于SpringBoot版本的不断升级和SpringFox摆烂不更新,导致了SpringBoot2.6之后的项目无法使用SpringFox去生成API文档,或者可以使用但是有很多的bug。

SpringDoc是一款可以结合SpringBoot使用API文档生成工具,基于OpenAPI 3,而且项目维护和社区都在不断更新,不仅支持SpringMVC,而且还支持Spring WebFlux项目。

下图为SpringDoc的架构图的总体概述。
在这里插入图片描述

2 基本使用

2.1 新建项目并导入maven

<dependency>    <groupId>org.springdocgroupId>    <artifactId>springdoc-openapi-uiartifactId>    <version>1.7.0version>dependency>

2.2 使用注解标记接口

2.2.1 常用注解
注解描述
@Tag标记在接口类上,用来设置 Controller 的名称和描述
@Parameter/@Parameters用来设置请求参数的描述
@Operation对接口方法的描述,可以设置接口的名称
@ApiResponse/@ApiResponses用来配置响应
@Schema标记在模型(model)类上或类的属性上,进行标注解释。
2.2.2 测试Controler Demo

TestController

package org.example.controller.test;@Tag(name = "测试接口", description = "定义测试接口")@RestController@RequestMapping("/test")public class TestController {    @Operation(summary = "get测试接口", description = "返回id")    @Parameter(name = "id", description = "参数ID", example = "123456")    @ApiResponse(responseCode = "403", description = "无权限")    @GetMapping("/get")    public Map<String, Object> get(@Parameter(description = "id") String id) {        Map<String, Object> res = new HashMap<>(1);        res.put("id", id);        return res;    }}

UserController

package org.example.controller.user;@Tag(name = "用户接口", description = "定义用户接口")@RestController@RequestMapping("/user")public class UserController {    @Operation(summary = "post测试接口", description = "返回username")    @Parameter(name = "username", description = "参数username", example = "username")    @ApiResponse(responseCode = "403", description = "无权限")    @PostMapping("/post")    public Map<String, Object> get(@Parameter(description = "用户名") String username) {        Map<String, Object> res = new HashMap<>(1);        res.put("username", username);        return res;    }}

2.3 编写SpringDocConfig

2.3.1 常用springdoc的配置
package org.example.config;import io.swagger.v3.oas.models.Components;import io.swagger.v3.oas.models.ExternalDocumentation;import io.swagger.v3.oas.models.OpenAPI;import io.swagger.v3.oas.models.info.Contact;import io.swagger.v3.oas.models.info.Info;import io.swagger.v3.oas.models.info.License;import io.swagger.v3.oas.models.security.SecurityRequirement;import io.swagger.v3.oas.models.security.SecurityScheme;import org.springdoc.core.GroupedOpenApi;import org.springdoc.core.customizers.OpenApiCustomiser;import org.springdoc.core.customizers.OperationCustomizer;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class SpringDocConfig {    @Bean    public OpenAPI defaultOpenAPI() {//        return new OpenAPI()//                .info(info())//                .externalDocs(documentation())//                .components(new Components().addSecuritySchemes("Authorization", new SecurityScheme().name("认证").type(SecurityScheme.Type.HTTP)//                        .description("JWT认证").scheme("bearer").bearerFormat("JWT")));        return new OpenAPI().                info(info())                .externalDocs(documentation());    }    public Info info() {        return new Info()                .title("SpringDoc OpenApi")                .version("V1.0.0")                .description("测试spring doc open api")                .license(new License().name("许可证名称").url("许可证地址"))                .contact(new Contact().name("联系人").url("联想人链接"))                .summary("概要");    }    public ExternalDocumentation documentation() {        return new ExternalDocumentation().description("文档描述").url("文档地址");    }    @Bean    public GroupedOpenApi testApi() {        return GroupedOpenApi.builder()                .displayName("测试接口")                .group("test")                .packagesToScan("org.example.controller.test")                .build();    }    @Bean    public GroupedOpenApi userApi() {        return GroupedOpenApi.builder()                .displayName("用户接口")                .group("user")                .packagesToScan("org.example.controller.user")                .addOpenApiCustomiser(openApiCustomiser())                .addOperationCustomizer(operationCustomizer())                .build();    }    public OpenApiCustomiser openApiCustomiser() {        return api ->                api.components(new Components()                        .addSecuritySchemes("Authorization", new SecurityScheme().name("认证").type(SecurityScheme.Type.HTTP)    .description("JWT认证").scheme("bearer").bearerFormat("JWT"))                );    }    public OperationCustomizer operationCustomizer() {        return (operation, handlerMethod) -> {            operation.addSecurityItem(new SecurityRequirement().addList("Authorization"));            return operation;        };    }}
2.3.2 关于接口鉴权问题(jwt方式)

如以上配置所示,user接口设置了鉴权设置

对一个分组的接口添加鉴权的方式

@Bean    public GroupedOpenApi userApi() {        return GroupedOpenApi.builder()                .displayName("用户接口")                .group("user")                .packagesToScan("org.example.controller.user")                .addOpenApiCustomiser(openApiCustomiser())                .addOperationCustomizer(operationCustomizer())                .build();}public OpenApiCustomiser openApiCustomiser() {    return api ->            api.components(new Components()                    .addSecuritySchemes("Authorization", new SecurityScheme().name("认证").type(SecurityScheme.Type.HTTP).description("JWT认证").scheme("bearer").bearerFormat("JWT"))            );}public OperationCustomizer operationCustomizer() {    return (operation, handlerMethod) -> {        operation.addSecurityItem(new SecurityRequirement().addList("Authorization"));        return operation;    };}

如果嫌麻烦,可以设置全局设置

例如配置代码注释的部分添加全局配置

 @Bean    public OpenAPI defaultOpenAPI() {        return new OpenAPI()                .info(info())                .externalDocs(documentation())                .components(new Components().addSecuritySchemes("Authorization", new SecurityScheme().name("认证").type(SecurityScheme.Type.HTTP)                        .description("JWT认证").scheme("bearer").bearerFormat("JWT")));    }

2.4 启动效果

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

在这里插入图片描述

2.5 一些application的配置说明

2.5.1 springdoc-openapi 核心属性

官方链接:https://springdoc.org/#springdoc-openapi-core-properties

参数名称默认值描述
springdoc.api-docs.path/v3/api-docsString, 用于 Json 格式的 OpenAPI 文档的自定义路径。
springdoc.api-docs.enabledtrueBoolean. 禁用 springdoc-openapi 端点(默认为 /v3/api-docs)。
springdoc.packages-to-scan*List of Strings.要扫描的包列表(逗号分隔)
springdoc.paths-to-match**String.默认产生媒体类型。
springdoc.cache.disabledfalseBoolean. 禁用计算 OpenAPI 的 springdoc-openapi 缓存。
springdoc.show-actuatorfalseBoolean. 显示执行器端点。
springdoc.auto-tag-classtrueBoolean. 禁用 springdoc-openapi 自动标签。
springdoc.model-and-view-allowedfalseBoolean. 允许带有 ModelAndView 返回的 RestControllers 出现在 OpenAPI 描述中。
springdoc.override-with-generic-responsetrueBoolean. 当为 true 时,自动将 @ControllerAdvice 响应添加到所有生成的响应中。
springdoc.api-docs.groups.enabledtrueBoolean. 禁用 springdoc-openapi 组。
springdoc.group-configs[0].groupString.群名
springdoc.group-configs[0].display-nameString.组的显示名称。
springdoc.group-configs[0].packages-to-scan*List of Strings.要扫描组的包列表(逗号分隔)
springdoc.group-configs[0].paths-to-match/*List of Strings.组匹配的路径列表(逗号分隔)
springdoc.group-configs[0].paths-to-exclude``List of Strings.要为组排除的路径列表(逗号分隔)
springdoc.group-configs[0].packages-to-excludeList of Strings.要排除的包列表(逗号分隔)
springdoc.group-configs[0].produces-to-match/*List of Strings.The list of produces mediaTypes to match (逗号分隔)
springdoc.group-configs[0].consumes-to-match/*List of Strings.要匹配的消耗媒体类型列表(逗号分隔)
springdoc.group-configs[0].headers-to-match/*List of Strings.要匹配的标题列表(逗号分隔)
springdoc.webjars.prefix/webjarsString, 把swagger-ui的URL可见的webjars前缀换成spring-webflux。
springdoc.api-docs.resolve-schema-propertiesfalseBoolean. 在@Schema 上启用属性解析器(名称、标题和描述)。
springdoc.remove-broken-reference-definitionstrueBoolean. 禁用删除损坏的引用定义。
springdoc.writer-with-default-pretty-printerfalseBoolean. 启用 OpenApi 规范的漂亮打印。
springdoc.model-converters.deprecating-converter.enabledtrueBoolean. 禁用弃用模型转换器。
springdoc.model-converters.polymorphic-converter.enabledtrueBoolean. 禁用多态模型转换器。
springdoc.model-converters.pageable-converter.enabledtrueBoolean. 禁用可分页模型转换器。
springdoc.model-converters.sort-converter.enabledtrueBoolean. 禁用排序转换器。
springdoc.use-fqnfalseBoolean. 启用完全限定名称。
springdoc.show-endpointfalseBoolean. 使 spring security 登录端点可见。
springdoc.pre-loading-enabledfalseBoolean. 预加载设置以在应用程序启动时加载 OpenAPI。
springdoc.writer-with-order-by-keysfalseBoolean. 启用确定性/字母顺序。
springdoc.use-management-portfalseBoolean. 在执行器管理端口上公开 swagger-ui。
springdoc.disable-i18nfalseBoolean. 使用 i18n 禁用自动翻译。
springdoc.show-spring-cloud-functionstrueBoolean. 显示 spring-cloud-function Web 端点。
springdoc.api-docs.versionopenapi_3_0String. 选择OpenAPI 3.0OpenAPI 3.1(使用值OPENAPI_3_1)。
springdoc.default-flat-param-objectfalseBoolean. 默认展平参数。
springdoc.default-support-form-datafalseBoolean. 指定api接受表单数据时默认设置参数为表单数据。
springdoc.nullable-request-parameter-enabledtrueBoolean. 在 Kotlin 中默认启用对可空请求参数的支持。
springdoc.show-oauth2-endpointsfalseBoolean. 使 spring security oauth2-endpoint 可见。
2.5.2 swagger-ui核心属性

官方链接https://springdoc.org/#swagger-ui-properties

参数名称默认值描述
springdoc.swagger-ui.path/swagger-ui.htmlString, 用于 swagger-ui HTML 文档的自定义路径。
springdoc.swagger-ui.enabledtrueBoolean. 禁用 swagger-ui 端点(默认为 /swagger-ui.html)。
springdoc.swagger-ui.configUrl/v3/api-docs/swagger-configString. 从中获取外部配置文档的 URL。

2 从SpringFox迁移

   <dependency>      <groupId>org.springdocgroupId>      <artifactId>springdoc-openapi-uiartifactId>      <version>1.7.0version>   dependency>

前:

  @Bean  public Docket publicApi() {      return new Docket(DocumentationType.SWAGGER_2)              .select()              .apis(RequestHandlerSelectors.basePackage("org.github.springshop.web.public"))              .paths(PathSelectors.regex("/public.*"))              .build()              .groupName("springshop-public")              .apiInfo(apiInfo());  }  @Bean  public Docket adminApi() {      return new Docket(DocumentationType.SWAGGER_2)              .select()              .apis(RequestHandlerSelectors.basePackage("org.github.springshop.web.admin"))              .paths(PathSelectors.regex("/admin.*"))              .apis(RequestHandlerSelectors.withMethodAnnotation(Admin.class))              .build()              .groupName("springshop-admin")              .apiInfo(apiInfo());  }

现在:

  @Bean  public GroupedOpenApi publicApi() {      return GroupedOpenApi.builder()              .group("springshop-public")              .pathsToMatch("/public/**")              .build();  }  @Bean  public GroupedOpenApi adminApi() {      return GroupedOpenApi.builder()              .group("springshop-admin")              .pathsToMatch("/admin/**")              .addOpenApiMethodFilter(method -> method.isAnnotationPresent(Admin.class))              .build();  }

如果你只有一个 Docket - 删除它并添加属性到你的application.properties

springdoc.packagesToScan=package1, package2springdoc.pathsToMatch=/v1, /api/balance/**
  @Bean  public OpenAPI springShopOpenAPI() {      return new OpenAPI()              .info(new Info().title("SpringShop API")              .description("Spring shop sample application")              .version("v0.0.1")              .license(new License().name("Apache 2.0").url("http://springdoc.org")))              .externalDocs(new ExternalDocumentation()              .description("SpringShop Wiki Documentation")              .url("https://springshop.wiki.github.org/docs"));  }

3 使用 knife4j美化

在这里插入图片描述

3.1 使用方法

Knife4j是一个集Swagger2 和 OpenAPI3为一体的增强解决方案。

官网:https://doc.xiaominfo.com/

首先,引用Knife4j的starter,Maven坐标如下:

<dependency><groupId>com.github.xiaoymingroupId><artifactId>knife4j-openapi3-spring-boot-starterartifactId><version>4.1.0version>dependency>

然后删除之前的springdoc-openapi-ui

在这里插入图片描述

3.2 常用配置项

官方说明地址:https://doc.xiaominfo.com/docs/features/enhance

## knife4j的增强配置,不需要增强可以不配knife4j:  enable: true  setting:    language: zh_cn    enable-home-custom: true    home-custom-path: classpath:markdown/api-home.md    enable-footer-custom: true    footer-custom-content: 系统文档

来源地址:https://blog.csdn.net/zhongjianboy/article/details/130362180

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯