Spring Boot 3.0 spring-fox失效情况下在gateway网关使用spring-doc整合swagger
由于新的项目使用spring boot 3.1.5,spring-fox-swagger的依赖底层用的是javax依赖包,而spring boot 3.x版本都是jakarta依赖包,引入后启动项目则会报错:Type javax.servlet.http.HttpServletRequest not present。
网上的解决办法都是降低spring boot版本到3.0以下,这明显是头疼砍头的解决办法。既然spring-fox不能使用了,那我们要使用api文档还有什么办法呢?那就需要spring-doc了。
且因为spring-doc的普及性不及spring-fox高,大部分博客都是讲的东一句西一句,所以我大概整合了一下,这篇博客便诞生了。
SpringDoc简介
SpringDoc是一款可以结合SpringBoot使用的API文档生成工具,基于OpenAPI 3,目前在Github上已有1.7K+Star,更新发版还是挺勤快的,是一款更好用的Swagger库!值得一提的是SpringDoc不仅支持Spring WebMvc项目,还可以支持Spring WebFlux项目,甚至Spring Rest和Spring Native项目,总之非常强大,下面是一张SpringDoc的架构图。
gateway网关整合spring-doc
项目介绍:
技术栈:spring boot 3.1.5 + eureka注册中心 + gateway网关 + openfeign
项目结构如图:
一、父级pom文件引入
由于我的项目是微服务项目,按照规范先在父级pom文件控制版本,代码如下:
<!-- 版本控制 -->
<properties>
<springdoc-openapi-starter.version>2.2.0</springdoc-openapi-starter.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- springDoc -->
<!--webmvc-ui用于web项目(此处我是为了给子服务使用) -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>${springdoc-openapi-starter.version}</version>
</dependency>
<!--webflux-ui用于webflux项目(此处我是为了给gateway网关服务使用) -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webflux-ui</artifactId>
<version>${springdoc-openapi-starter.version}</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-common</artifactId>
<version>${springdoc-openapi-starter.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
二、子服务pom文件引入
此处我在两个业务服务中引入springdoc的webmvc-ui依赖,由于在父级pom文件控制了版本,所以此处不填写版本号,代码如下:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
</dependency>
子服务引入springdoc后,启动子服务,访问:http://localhost:8080/swagger-ui.html
可以发现swagger已经正常启用了,如果是单体服务那么就已经结束了,但是我们是微服务且需要在gateway网关聚合swagger文档,所以还需要继续在gateway网关服务继续做操作。
三、gateway网关整合
在网关服务中引入springdoc的webflux-ui依赖,由于在父级pom文件控制了版本,所以此处不填写版本号,代码如下:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webflux-ui</artifactId>
</dependency>
1.聚合子服务API文档
聚合子服务有两种配置方式,二者任选其一:
- 配置类自动配置
依赖引入后,继续在网关服务新建一个config类,代码如下:
import jakarta.annotation.PostConstruct;
import org.springdoc.core.properties.AbstractSwaggerUiConfigProperties;
import org.springdoc.core.properties.SwaggerUiConfigProperties;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionLocator;
import org.springframework.context.annotation.Configuration;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
@Configuration
public class SpringDocConfig {
protected final SwaggerUiConfigProperties swaggerUiConfigProperties;
protected final RouteDefinitionLocator routeDefinitionLocator;
public SpringDocConfig(SwaggerUiConfigProperties swaggerUiConfigProperties, RouteDefinitionLocator routeDefinitionLocator) {
this.swaggerUiConfigProperties = swaggerUiConfigProperties;
this.routeDefinitionLocator = routeDefinitionLocator;
}
@PostConstruct
public void autoInitSwaggerUrls() {
List<RouteDefinition> definitions = routeDefinitionLocator.getRouteDefinitions().collectList().block();
definitions.stream().forEach(routeDefinition -> {
AbstractSwaggerUiConfigProperties.SwaggerUrl swaggerUrl = new AbstractSwaggerUiConfigProperties.SwaggerUrl(
routeDefinition.getId().replace("ReactiveCompositeDiscoveryClient_", "").toLowerCase(),
routeDefinition.getUri().toString().replace("lb://", "").toLowerCase() + "/v3/api-docs",
routeDefinition.getId().replace("ReactiveCompositeDiscoveryClient_", "").toLowerCase()
);
Set<AbstractSwaggerUiConfigProperties.SwaggerUrl> urls = swaggerUiConfigProperties.getUrls();
if (urls == null) {
urls = new LinkedHashSet<>();
swaggerUiConfigProperties.setUrls(urls);
}
urls.add(swaggerUrl);
});
}
}
该config类的作用是自动解析子服务的swagger文档,无需手动配置。
- 配置文件手动配置
示例如下:
spring:
cloud:
gateway:
discovery:
locator:
enabled: true
routes:
...
# ==============================================================
# apidocs资源路由配置
- id: hello-api-doc
uri: lb://sample-hello/
predicates:
## 转发地址格式为 uri/archive
- Path=/sample-hello/v3/api-docs/**
filters:
- StripPrefix=1
springdoc:
...
swagger-ui:
urls:
- name: 网关服务接口
url: /v3/api-docs
- name: Hello服务
# url前缀要与路由配置中的Patch呼应。
url: /sample-hello/v3/api-docs
这个方法简单粗暴。可以快速验证。而且可以灵活的控制需要暴露的服务接口。不过有两个问题:
首先如果子服务太多,配置量会比较大;其二apidocs的路由配置需要与其它正常业务路由写死在配置中,在生产环境下不方便剥离。会有安全隐患。
四、效果演示
整合完成后,依次重启eureka注册中心、网关、子服务等,访问 网关地址+/swagger-ui/index.html(我的本地地址是:http://localhost/swagger-ui.html) 即可看见聚合后的swagger文档。可以方便的切换不同服务的api文档,如下图所示:
切换不同的子服务api文档:
总结
以上就是简单的一个gateway网关服务整合spring-doc的教程,与spring-fox的差异以及具体的使用可以前往官网研究,此处不做多的赘述了。
文章参考:
https://springdoc.org/
https://blog.csdn.net/zhenghongcs/article/details/123812583
https://blog.csdn.net/qq_39609993/article/details/126136180