写在前面
在基于SpringCloud的项目中,各个微服务都有基于SWAGGER的在线API文档,所以将SWAGGER在线构建API文档创建了一个公共的场景启动器。如果要查看多个API文档怎么办呢? 一般会输入不同的IP:PORT查看不同微服务的文档,这样比较麻烦,所以将SWAGGER与GATEWAY进行聚合和集成,仅仅通过切换即可方便的查看。
操作步骤
1. 添加依赖
<!-- Swagger -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
</dependency>
2. 创建聚合系统接口
/**
* 聚合系统接口
* @author ROCKY
*/
@Component
@Primary
@AllArgsConstructor
public class SwaggerProvider implements SwaggerResourcesProvider {
// SWAGGER3默认的URL后缀
public static final String SWAGGER3URL = "/v3/api-docs";
// 网关路由
@Autowired
private RouteLocator routeLocator;
@Autowired
private GatewayProperties gatewayProperties;
// 聚合其他服务接口
@Override
public List<SwaggerResource> get() {
List<SwaggerResource> resourceList = new ArrayList<>();
List<String> routes = new ArrayList<>();
// 获取网关中配置的route
routeLocator.getRoutes().subscribe(route -> routes.add(route.getId()));
gatewayProperties.getRoutes().stream()
.filter(routeDefinition -> routes
.contains(routeDefinition.getId()))
.forEach(routeDefinition -> routeDefinition.getPredicates().stream()
.filter(predicateDefinition -> "Path".equalsIgnoreCase(predicateDefinition.getName()))
.forEach(predicateDefinition -> resourceList
.add(swaggerResource(routeDefinition.getId(), predicateDefinition.getArgs()
.get(NameUtils.GENERATED_NAME_PREFIX + "0").replace("/**", SWAGGER3URL)))));
return resourceList;
}
private SwaggerResource swaggerResource(String name, String location) {
SwaggerResource swaggerResource = new SwaggerResource();
swaggerResource.setName(name);
swaggerResource.setLocation(location);
swaggerResource.setSwaggerVersion("3.0");
return swaggerResource;
}
}
3.创建swagger-resources的控制器
/**
* SWAGGER-RESOURCES控制对象
* @author ROCKY
*/
@RestController
@RequestMapping("/swagger-resources")
public class SwaggerHandler {
@Autowired(required = false)
private SecurityConfiguration securityConfiguration;
@Autowired(required = false)
private UiConfiguration uiConfiguration;
private final SwaggerResourcesProvider swaggerResources;
@Autowired
public SwaggerHandler(SwaggerResourcesProvider swaggerResources) {
this.swaggerResources = swaggerResources;
}
@GetMapping("/configuration/security")
public Mono<ResponseEntity<SecurityConfiguration>> securityConfiguration() {
return Mono.just(new ResponseEntity<>(
Optional.ofNullable(securityConfiguration)
.orElse(SecurityConfigurationBuilder.builder().build()),
HttpStatus.OK));
}
@GetMapping("/configuration/ui")
public Mono<ResponseEntity<UiConfiguration>> uiConfiguration() {
return Mono.just(new ResponseEntity<>(
Optional.ofNullable(uiConfiguration)
.orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK));
}
@SuppressWarnings("rawtypes")
@GetMapping("")
public Mono<ResponseEntity> swaggerResources() {
return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));
}
}
4. APPLICATION.YML
在APPLICATION.YML需要进行以下配置,同时注意需要添加filters。
server:
port: 8080
spring:
application:
name: servicex-gateway
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
globalcors:
corsConfigurations:
'[/**]':
allowedOriginPatterns: "*"
allowed-methods: "*"
allowed-headers: "*"
allow-credentials: true
exposedHeaders: "Content-Disposition,Content-Type,Cache-Control"
locator:
enabled: true
lowerCaseServiceId: true
routes:
# 唯一标识 - 系统核心服务
- id: servicex-system
uri: lb://servicex-system
predicates:
- Path=/api/servicex/system/**
filters:
- StripPrefix=3
# 唯一标识 - 系统用户服务
- id: servicex-user
uri: lb://servicex-user
predicates:
- Path=/api/servicex/user/**
filters:
- StripPrefix=3
# 唯一标识 - 商品服务
- id: servicex-mallx-spu
uri: lb://servicex-mallx-spu
predicates:
- Path=/api/servicex/mallx/spu/**
filters:
- StripPrefix=4
# 唯一标识 - 订单服务
- id: servicex-mallx-order
uri: lb://servicex-mallx-order
predicates:
- Path=/api/servicex/mallx/order/**
filters:
- StripPrefix=4
4. 访问方式
http://网关IP:8080/swagger-ui/index.html