springdoc-openapi的集成与常见问题

在项目中经常使用swagger来作为项目接口的自动化api文档,尤其是springboot项目,一般都是通过springfox-boot-starter来集成swagger的使用。
springfox-boot-starter 在2.x时代用着很方便,但是随着项目的发展,尤其是spring项目的不断推出新版本,
springfox-boot-starter在3.0版本就已经明显存在兼容性问题了,而且已经3年多没维护了,所以寻找替代品是一种虽然不紧迫但很必须的事项了。
而springdoc-openapi就是springfox-boot-starter的替代品,且获得了swagger的官方支持,算是springfox在springboot高版本的天热替代品。
springfox已经3年未更新了

本文就介绍springdoc-openapi的集成与常见问题。

项目依赖

如果你的项目是springboot2.x版本,请使用springdoc-openapi的1.x版本。
如果你的项目是springboot3.x版本,请使用springdoc-openapi的2.x版本。

本文案例的环境是:

  • java 17
  • springboot 2.7.18

开始

使用idea创建一个新的maven springboot项目,添加如下依赖

1
2
3
4
5
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.7.0</version>
</dependency>

创建一个Controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@RestController
@RequestMapping("/hello")
@Tag(name="openapi demo")
public class HelloWorldController {

@GetMapping("/world")
@Operation(summary = "helloWorld接口",description = "接口描述信息")
@Parameter(name = "name", description = "名称", required = true, in = ParameterIn.QUERY)
public String helloWorld(String name) {
return "Hello "+ Optional.of(name).orElse("world");
}

/**
* 隐藏的api,不再swagger 显示
*/
@GetMapping("/hidden")
public String hiddenApi(String name) {
return "Hello "+ Optional.of(name).orElse("world");
}
}

然后就可以直接启动了,不用任何配置,就可以看到swagger的界面了。
swagger默认地址: http://localhost:8080/swagger-ui/index.html#/
springdoc版的swagger的默认页面

通过配置文件修改相关配置

如果你不想使用默认的配置,可以通过配置文件修改相关配置。比如我通过下面配置对swagger的界面进行了微调。

1
2
3
4
5
6
7
8
9
# application.properties
springdoc.swagger-ui.disable-swagger-default-url=true
# 布局 StandaloneLayout,BaseLayout
springdoc.swagger-ui.layout=BaseLayout
springdoc.swagger-ui.path=/v3/swagger-ui.html
# swagger-ui 默认关联的api接口配置, 要与api-docs.path 一致。 不配置默认取api-docs.path配置
springdoc.swagger-ui.url=/v3/test/api-docs
# api json 接口配置, 可以自定义其他json接口
springdoc.api-docs.path=/v3/test/api-docs

因为修改了swagger页面的访问地址,所以我们的访问地址变成了:
http://localhost:8080/v3/swagger-ui/index.html#/
效果如图:
springdoc版的swagger的properties配置版

通过自定义配置类修改相关配置

如果我们想要更自有的配置,可以通过自定义配置类来修改相关配置。

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
@Configuration
public class SwaggerConfig {
/**
* 添加摘要信息
*/
@Bean
public OpenAPI openAPI() {
return new OpenAPI()
.info(new Info().title("hancher demo open api")
.description("helloWorld接口文档")
.version("v3.0.0")
// 联系人
.contact(new Contact().name("寒澈").url("https://www.hancher.top/"))
)
// 其他文档信息
.externalDocs(new ExternalDocumentation()
.description("寒澈笔记")
.url("https://www.hancher.top/"));
}


/**
* 模式三: 自定义api分组
*
*/
// @Bean
public GroupedOpenApi publicApi() {
return GroupedOpenApi.builder()
.packagesToScan("com.hancher.demo.springbootopenapi.controller") // 扫描包
.displayName("寒澈openapi")
.addOpenApiMethodFilter(method -> method.isAnnotationPresent(Operation.class))
.build();
}
}

还是默认访问地址:http://localhost:8080/swagger-ui/index.html#/
springdoc版的swagger的openapi配置版

迁移成本

除了将老版本的注解替换成新的注解之外,没有任何其他改的。
springfox迁移到springdoc的注解变动

集成中遇到的问题

我在集成过程中遇到的最大的问题就是明明集成好了,但是swagger的访问页面还是swagger的默认petStore的页面,而不是我配置的controller的页面。这个问题让我排查了好久。
springdoc总是显示默认petstore接口

首先,我们我们要先了解的是,swagger-ui是一套api展示页面,他的数据是从v3/api-docs接口获取的json数据。
所以排查问题,我们首先要看页面有没有调用这个接口(有可能我们在配置文件了将这个接口改了),再次看看这个接口有没有返回正常的json结果。
springdoc的数据接口
如果这这个接口返回了正常的数据,且是我们的配置的接口数据,那么问题很可能是我们的一些安全配置将swagger的相关接口给屏蔽了。
比如WebSecurityConfigurerAdapter, 我就是在这个环节上出的问题

1
2
3
4
5
6
7
8
9
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception
{

}
}

项目demo

集成了application,java bean config 两种方式的demo
springdoc-demo


springdoc-openapi的集成与常见问题
https://www.hancher.top/2023/11/29/spring-springdoc-openapi/
作者
寒澈
发布于
2023年11月29日
许可协议