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-docs | String , 用于 Json 格式的 OpenAPI 文档的自定义路径。 |
springdoc.api-docs.enabled | true | Boolean . 禁用 springdoc-openapi 端点(默认为 /v3/api-docs)。 |
springdoc.packages-to-scan | * | List of Strings .要扫描的包列表(逗号分隔) |
springdoc.paths-to-match | ** | String .默认产生媒体类型。 |
springdoc.cache.disabled | false | Boolean . 禁用计算 OpenAPI 的 springdoc-openapi 缓存。 |
springdoc.show-actuator | false | Boolean . 显示执行器端点。 |
springdoc.auto-tag-class | true | Boolean . 禁用 springdoc-openapi 自动标签。 |
springdoc.model-and-view-allowed | false | Boolean . 允许带有 ModelAndView 返回的 RestControllers 出现在 OpenAPI 描述中。 |
springdoc.override-with-generic-response | true | Boolean . 当为 true 时,自动将 @ControllerAdvice 响应添加到所有生成的响应中。 |
springdoc.api-docs.groups.enabled | true | Boolean . 禁用 springdoc-openapi 组。 |
springdoc.group-configs[0].group | String .群名 | |
springdoc.group-configs[0].display-name | String .组的显示名称。 | |
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-exclude | List 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 | /webjars | String , 把swagger-ui的URL可见的webjars前缀换成spring-webflux。 |
springdoc.api-docs.resolve-schema-properties | false | Boolean . 在@Schema 上启用属性解析器(名称、标题和描述)。 |
springdoc.remove-broken-reference-definitions | true | Boolean . 禁用删除损坏的引用定义。 |
springdoc.writer-with-default-pretty-printer | false | Boolean . 启用 OpenApi 规范的漂亮打印。 |
springdoc.model-converters.deprecating-converter.enabled | true | Boolean . 禁用弃用模型转换器。 |
springdoc.model-converters.polymorphic-converter.enabled | true | Boolean . 禁用多态模型转换器。 |
springdoc.model-converters.pageable-converter.enabled | true | Boolean . 禁用可分页模型转换器。 |
springdoc.model-converters.sort-converter.enabled | true | Boolean . 禁用排序转换器。 |
springdoc.use-fqn | false | Boolean . 启用完全限定名称。 |
springdoc.show-endpoint | false | Boolean . 使 spring security 登录端点可见。 |
springdoc.pre-loading-enabled | false | Boolean . 预加载设置以在应用程序启动时加载 OpenAPI。 |
springdoc.writer-with-order-by-keys | false | Boolean . 启用确定性/字母顺序。 |
springdoc.use-management-port | false | Boolean . 在执行器管理端口上公开 swagger-ui。 |
springdoc.disable-i18n | false | Boolean . 使用 i18n 禁用自动翻译。 |
springdoc.show-spring-cloud-functions | true | Boolean . 显示 spring-cloud-function Web 端点。 |
springdoc.api-docs.version | openapi_3_0 | String . 选择OpenAPI 3.0 或OpenAPI 3.1 (使用值OPENAPI_3_1 )。 |
springdoc.default-flat-param-object | false | Boolean . 默认展平参数。 |
springdoc.default-support-form-data | false | Boolean . 指定api接受表单数据时默认设置参数为表单数据。 |
springdoc.nullable-request-parameter-enabled | true | Boolean . 在 Kotlin 中默认启用对可空请求参数的支持。 |
springdoc.show-oauth2-endpoints | false | Boolean . 使 spring security oauth2-endpoint 可见。 |
2.5.2 swagger-ui核心属性
官方链接https://springdoc.org/#swagger-ui-properties
参数名称 | 默认值 | 描述 |
---|---|---|
springdoc.swagger-ui.path | /swagger-ui.html | String , 用于 swagger-ui HTML 文档的自定义路径。 |
springdoc.swagger-ui.enabled | true | Boolean . 禁用 swagger-ui 端点(默认为 /swagger-ui.html)。 |
springdoc.swagger-ui.configUrl | /v3/api-docs/swagger-config | String . 从中获取外部配置文档的 URL。 |
2 从SpringFox迁移
- 删除 springfox 和 swagger 2 依赖项。添加
springdoc-openapi-ui
依赖项。
<dependency> <groupId>org.springdocgroupId> <artifactId>springdoc-openapi-uiartifactId> <version>1.7.0version> dependency>
- 用 swagger 3 注释替换 swagger 2 注释(它已经包含在
springdoc-openapi-ui
依赖项中)。swagger 3 注释的包是io.swagger.v3.oas.annotations
.@Api
→@Tag
@ApiIgnore
→@Parameter(hidden = true)
或@Operation(hidden = true)
或@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")
- 如果您使用一个对象来捕获多个请求查询参数,请注释该方法参数
@ParameterObject
- 此步骤是可选的:仅当您有多个
Docket
beans 时才用GroupedOpenApi
beans 替换它们。
前:
@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/**
- 添加
OpenAPI
类型的bean。参见示例:
@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为一体的增强解决方案。
首先,引用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