上篇我用gateway实现了,服务的熔断,这篇文章我来实现,gateway聚合swagger Api文档,实现统一路由,多模块切换,先来看一下聚合后的效果图:
通过上边的图片我们看到了预期的效果,并且这个api的文档,更像是一个后台的管理系统,功能更加强大!接下来我们进行实现!
一.依赖管理
这里我们进行了ui的更换
<properties>
<knife4j.version>1.9.6</knife4j.version>
<springfox.version>2.9.2</springfox.version>
<swagger.version>1.5.21</swagger.version>
</properties>
<dependencies>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>${knife4j.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${springfox.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-bean-validators</artifactId>
<version>${springfox.version}</version>
</dependency>
</dependencies>
二.Gateway 配置
2.1 swagger 相关配置
@Component
public class SwaggerHeaderFilter extends AbstractGatewayFilterFactory {
private static final String HEADER_NAME = "X-Forwarded-Prefix";
private static final String URI = "/v2/api-docs";
@Override
public GatewayFilter apply(Object config) {
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
String path = request.getURI().getPath();
if (!StringUtils.endsWithIgnoreCase(path,URI )) {
return chain.filter(exchange);
}
String basePath = path.substring(0, path.lastIndexOf(URI));
ServerHttpRequest newRequest = request.mutate().header(HEADER_NAME, basePath).build();
ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();
return chain.filter(newExchange);
};
}
}
@Slf4j
@Component
@Primary
@AllArgsConstructor
public class SwaggerProvider implements SwaggerResourcesProvider {
private final RouteLocator routeLocator;
private final GatewayProperties gatewayProperties;
@Override
public List<SwaggerResource> get() {
List<SwaggerResource> resources = new ArrayList<>();
List<String> routes = new ArrayList<>();
routeLocator.getRoutes().subscribe(route -> routes.add(route.getId()));
gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId())).forEach(route -> {
route.getPredicates().stream()
.filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName()))
.forEach(predicateDefinition -> resources.add(swaggerResource(route.getId(),
predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0")
.replace("**", "v2/api-docs"))));
});
return resources;
}
private SwaggerResource swaggerResource(String name, String location) {
log.info("name:{},location:{}",name,location);
SwaggerResource swaggerResource = new SwaggerResource();
swaggerResource.setName(name);
swaggerResource.setLocation(location);
swaggerResource.setSwaggerVersion("2.0");
return swaggerResource;
}
}
@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));
}
@GetMapping("")
public Mono<ResponseEntity> swaggerResources() {
return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));
}
}
2.2 多模块配置
这里配置需要进行统一管理的api文档服务
gateway:
discovery:
locator:
enabled: true
# 服务名小写
lower-case-service-id: true
routes:
- id: api-javayh-demo
# lb代表从注册中心获取服务,且已负载均衡方式转发
uri: lb://javayh-demo
predicates:
- Path=/javayh-demo/**
# 加上StripPrefix=1,否则转发到后端服务时会带上demo前缀
filters:
- SwaggerHeaderFilter
- StripPrefix=1
# 服务降级 触发调用 HystrixFallbackHandler GatewayFallbackConfig
- name: Hystrix
args:
name: default
fallbackUri: 'forward:/defaultfallback'
三.单体服务配置
@Configuration
@EnableSwagger2
@EnableSwaggerBootstrapUI
@Import(BeanValidatorPluginsConfiguration.class)
public class SwaggerConfig {
@Bean
@Order(value = 1)
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Swagger API")
.description("test")
.termsOfServiceUrl("")
.contact(new Contact("Yang Haiji", "", ""))
.version("2.0")
.build();
}
这时我们启动gateway 和需要统一管理的服务,效果如下,这里提供了很多功能,大家可以自行的发掘!
以上的源码一上传到github:https://github.com/Dylan-haiji/javayh-platform
本文的分享暂时就到这里,希望对您有所帮助
关注 Java有货领取更多资料
联系小编。微信:372787553,带您进群互相学习
- SpringCloud 自定义封装架构https://github.com/Dylan-haiji/javayh-platform
- Java 设计模式学习代码 https://github.com/Dylan-haiji/design-pattern
- SpringCloud学习代码: https://github.com/Dylan-haiji/javayh-cloud
- AlibabaCloud学习代码:https://github.com/Dylan-haiji/javayh-cloud-nacos
- SpringBoot+Mybatis 多数据源切换:https://github.com/Dylan-haiji/javayh-boot-data-soure
- Redis、Mongo、Rabbitmq、Kafka学习代码: https://github.com/Dylan-haiji/javayh-middleware
- SpringBoot+SpringSecurity实现自定义登录学习代码:https://github.com/Dylan-haiji/javayh-distribution