当Spring Boot升到3.0以后,之前基于springfox的swagger就会报Failed to load API definition错误了。

Swagger是一个RESTful API开源框架,主要是帮助开发者设计、构建、文档化和测试API。Swagger的核心思想是通过定义和描述API的规范、结构和交互方式,以提高API的可读性、可靠性和易用性,同时降低API开发的难度和调用者之间的沟通成本。
大家用得比较多的springfox-swagger2和springfox-boot-starter都是基于Swagger 2.x,只适用于Spring Boot 3.0以下版本。Spring Boot 3.0以后必须使用基于Open API 3.0的springdoc-openapi。
我们有必要了解一下swagger的发展历程。
Swagger是由Tony Tam在2011年开发的,之后被SmartBear Software公司收购。Swagger经历了许多重大的更新和变化,大概可以分为以下三个发展阶段:
1.Swagger 1.x阶段(2011-2014年):Swagger最初是一个简单的API文档生成工具,通过对JAX-RS和Jersey注解的支持自动生成API文档,使得API文档的维护变得更加容易。在这个阶段,Swagger还没有完全成熟,只支持基本API描述和文档生成。
2.Swagger 2.x阶段(2014-2017年):这个阶段Swagger发生了重大变化,它不再仅仅只是一个文档生成工具,而是一个完整的API开发和管理平台。Swagger 2.x加入了强大的注解支持,可以描述API的细节信息,如请求参数、返回类型等,以及定义RESTful API的元数据,如API描述、标签等。此外,Swagger 2.x还引入了OpenAPI规范,在API定义方面有了更严格的标准和规则。
3.OpenAPI阶段(2017-至今,也被称为Swagger 3.x):在2017年,Swagger 2.x的规范成为了Linux基金会旗下的OpenAPI规范。这标志着Swagger从一款工具演变成为了一个开放且标准的API定义框架。OpenAPI规范不仅继承了Swagger 2.x的特性,还提供了更加全面和严格的API定义规范,并且扩展了对非RESTful API的支持。随着OpenAPI规范的普及,越来越多的API开发者开始使用Swagger/OpenAPI来开发、测试和文档化他们的RESTful API。随着Linux基金会旗下的OpenAPI收购了Swagger2.x后对其进行了更严格的规范,又进行了各种优化,所以我们也可以称OpenAPI是一个全新的Swagger3.x。
除了上述几个主要阶段之外,还有一些其他重要的事件和版本,如Swagger UI、Swagger Codegen、SwaggerHub等等。这些工具和服务进一步扩展了Swagger的功能,使其成为了一个更加完整、强大和易于使用的API定义和管理平台。
Springfox是一个用于集成Swagger2.x到Spring应用程序中的库,大家用得比较多的是springfox-swagger2和springfox-boot-starter,Springfox最新版本是3.0.0在2020年就已经停止更新了。
SpringDoc是基于OpenAPI 3.0规范构建的库,对应的是springdoc-openapi,因此推荐在Spring Boot 2.4及以上版本中使用springdoc-openapi库来集成Swagger3.x。
springdoc-openapi的java库帮助spring boot项目自动生成API文档。springdoc-openapi通过在运行时检查应用程序来根据spring配置、类结构和各种注释推断API语义,自动生成JSON/YAML和HTML格式API的文档,此文档可以通过使用swagger-api annotations注解来完成。

springdoc-openapi最新版本是2.2.0,Spring Boot 2.x和1.x要使用springdoc-openapi v1系列(最新版本是1.7.0)。
springdoc-openapi支持以下内容:
OpenAPI 3
Spring-boot v3 (Java 17 & Jakarta EE 9)
JSR-303, specifically for @NotNull, @Min, @Max, and @Size.
Swagger-ui
OAuth 2
GraalVM native images
由于Springfox和SpringDoc是基于不同的实现,因此它们存在一些差异、涉及到很大改动,因此如果是Spring Boot 3.0以下版本还可以正常使用swagger,不建议将原有的Springfox换成SpringDoc。
下面以springdoc-openapi v2.2.0为例来讲解Spring Boot 3.0以后基于springdoc-openapi的swagger解决方案,v1.7.0及以下版本参考官网:springdoc-openapi v1.7.0。
只要引入springdoc-openapi-starter-webmvc-ui即可集成spring-boot和swagger-ui,不需要额外的配置,注意,不需要额外的配置哦!
//maven版
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.2.0</version>
</dependency>
//gradle版
implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0"

需要注意的是,Spring Boot 3.0要求JDK 17及以上,因此“Settings->Build, Execution, Deployment->Build Tools->Gradle->Gradle JVM”、“Settings->Build, Execution, Deployment->Build Tools->Maven->Importing->JDK for importer”、“Project Structure->Project Settings->Project->SDK”等都要设置成JDK 17及以上版本。
如果是从Springfox迁移到SpringDoc,可以把之前的全部配置去掉,然后将对应的注解改过来即可,其中包名由“io.swagger.annotations.*”改成“io.swagger.v3.oas.annotations”,注解变化如下。
@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")
需要注意的是,实体类和属性都用@Schema,要隐藏实体类的某个字段得用@Schema(hidden = true)。
各种配置可以在application.yml或application.properties中配置,官方提供了下面的配置自定义swagger访问地址。
# applicationl.yml配置
springdoc:
swagger-ui:
path: /demo-swagger-ui.html
# applicationl.properties配置
springdoc.swagger-ui.path=/demo-swagger-ui.html
但是,你会发现最后都是跳转到“/swagger-ui/index.html”URI,如果非要改变swagger访问地址可以加context-path,但是css、js等资源路径都得加上该context-path,最后的URI是“/demo/swagger-ui/index.html”。
# applicationl.yml配置
server:
servlet:
context-path: /demo
# applicationl.properties配置
server.servlet.context-path=/demo
可以加个Bean来配置swagger信息。
import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* springdoc-openapi配置类
* @Author https://www.xubingtao.cn
* @DateTime 2023/09/27 17:10
*/
@Configuration
public class OpenApiConfig {
@Bean
public OpenAPI springOpenAPI() {
return new OpenAPI()
// .openapi("2.0")
.info(new Info()
.title("微服务多端跨平台系统后台")
.description("该服务下包含多个模块,developed by xubingtao.cn。")
.version("1.0.0")
.license(new License().name("Apache 2.0").url("https://springdoc.org")))
.externalDocs(new ExternalDocumentation()
.description("SpringShop Wiki Documentation")
.url("https://springshop.wiki.github.org/docs"));
}
}
可能会遇到“Unable to render this definition”问题。
Unable to render this definition
The provided definition does not specify a valid version field.
Please indicate a valid Swagger or OpenAPI version field. Supported version fields are swagger: "2.0" and those that match openapi: 3.x.y (for example, openapi: 3.1.0).
这可能是由于Controller层中含有private私有方法、同一Controller层中同一请求类型包含多个相同请求路径、传入参数模型带有异常符号、swagger自带接口的返回值结构不正确,我遇到的问题是实现WebMvcConfigurer接口重写configureMessageConverters用HttpMessageConverter转换数据类型造成的。

如果实在找不到问题可以通过排除法,先把各种配置去掉只留下一个controller,然后逐个添加,直到调试出问题。
更多相关内容请访问官网:OpenAPI 3 Library for spring-boot。
需要示例代码可以到分享录公众号发送关键字“s4543”获取。
展开阅读全文
上一篇: Spring Security 6.0弃用WebSecurityConfigurerAdapter后的解决方案
下一篇:APP备案教程