前言
由于项目原因,需要将网关从zuul升级到gateway网关,由于 gateway网关底层是基于webflux的,导致原先在网关中集成的swagger不可用。
那么如何在gateway网关中整合swagger呢?
一、maven依赖配置
核心是将swagger升级到了3.0.0版本。
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.4.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <java.version>1.8</java.version> <spring-cloud.version>Hoxton.SR8</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-boot-starter</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies>
说明:
将swagger升级到3.0.0可用支持webflux,同时有以下这些变化:
1、自动化注解变更:由之前的 @EnableSwagger2 更改为 @EnableOpenApi,当然@EnableOpenApi可以放在配置类,也可以放在启动类上
2、页面访问变更:
项目访问地址从2.x的 http://localhost:8080/swagger-ui.html 到 3.x的 http://localhost:8080/swagger-ui/index.html 或 http://localhost:8080/swagger-ui/
注:@EnableSwagger2在springfox3版本依然可以继续使用
3、DocumentationType变更
Docket构造函数中的DocumentationType指向更改:由之前的DocumentationType.SWAGGER_2 更改为 DocumentationType.OAS_30
注:DocumentationType.SWAGGER_2在springfox3版本依然可以继续使用
二、属性配置
这里主要通过指定springfox.documentation.swagger-ui.base-url属性,将swagger页面的访问地址和网关的API路由前缀统一起来。
swagger的访问地址为:http://localhost:8020/api/v1/swagger-ui/index.html
server.port=8020 spring.application.name=gateway spring.profiles.active=dev spring.cloud.gateway.api-prefix=/api/v1 springfox.documentation.swagger-ui.base-url=${spring.cloud.gateway.api-prefix} #配置网关的默认路由 spring.cloud.gateway.enabled=true spring.cloud.gateway.discovery.locator.enabled=true spring.cloud.gateway.discovery.locator.lower-case-service-id=true management.endpoints.web.exposure.include=gateway #注册中心 eureka.client.service-url.defaultZone=http://wxswjAuth:admin2578@register1:8001/eureka/ eureka.instance.prefer-ip-address=true eureka.instance.hostname=${spring.cloud.client.ip-address} eureka.instance.instance-id=${eureka.instance.hostname}:${server.port}
三、代码
1、启动类上添加@EnableOpenApi注解
@SpringBootApplication(exclude = { GatewayDiscoveryClientAutoConfiguration.class }) @EnableDiscoveryClient @Slf4j @EnableOpenApi public class WxswjGatewayApplication { public static void main(String[] args) { SpringApplication.run(WxswjGatewayApplication.class, args); log.info("网关服务启动成功!"); } }
2、实现SwaggerResourcesProvider,聚合注册中心上服务的swagger(这里过滤了网关服务本身)
细节方面是在配置routeHosts的路由地址时,也添加网关的统一路由前缀。
// 拼接url ,请求swagger的url String url = prefix + “/”+ instance.toLowerCase() + SWAGGER2URL;
@Component @Primary public class SwaggerProvider implements SwaggerResourcesProvider { @Value("${spring.cloud.gateway.api-prefix:/api/v1}") private String prefix; /** * swagger2默认的url后缀 */ private static final String SWAGGER2URL = "/v2/api-docs"; // private static final String OAS_30_URL = "/v3/api-docs"; @Autowired private RouteLocator routeLocator; @Autowired private GatewayProperties gatewayProperties; /** * 网关应用名称 */ @Value("${spring.application.name}") private String self; @Override public List<SwaggerResource> get() { List<SwaggerResource> resources = new ArrayList<>(); List<String> routeHosts = new ArrayList<>(); routeLocator.getRoutes() .filter(route -> route.getUri().getHost() != null) .filter(route -> route.getUri().getHost() != null) .filter(route -> Objects.equals(route.getUri().getScheme(), "lb")) //过滤掉网关自身的服务 uri中的host就是服务id .filter(route -> !self.equalsIgnoreCase(route.getUri().getHost())) .subscribe(route -> routeHosts.add(route.getUri().getHost())); // 记录已经添加过的server,存在同一个应用注册了多个服务在注册中心上 Set<String> dealed = new HashSet<>(); routeHosts.forEach(instance -> { // 拼接url ,请求swagger的url String url = prefix + "/"+ instance.toLowerCase() + SWAGGER2URL; if (!dealed.contains(url)) { dealed.add(url); SwaggerResource swaggerResource = new SwaggerResource(); swaggerResource.setUrl(url); swaggerResource.setName(instance); //swaggerResource.setSwaggerVersion("3.0.3"); resources.add(swaggerResource); } }); return resources; } }
四、访问
http://localhost:8020/api/v1/swagger-ui/index.html
总结
本文主要是通过将swagger升级到3.0.0版本,实现了在gateway网关中聚合swagger。