当前位置:

spring cloud gateWay 集成 knife4j实现swagger文档聚合

访客 2024-01-05 1490 0

一、背景

项目开发中前后端衔接有多种工具,我们选用的是swagger,一个版本下来复盘的时候项目组成员反馈不好用,接口难找,页面也很不美观;于是寻找集成的方式将微服务多个项目集成到一起,最终选择springcloudgateWayknife4j方案,因为我们网关用的是springcloudgateWay,knife4j相当于swagger增强版。

每个单体架构中引入knife4j生成接口的在线文档,采用gateWay将后端所有接口整合到统一的入口去访问,所以需要将gateWay和knife4j结合,实现各微服务的文档聚合。

二、集成步骤

1、springboot集成knife4j

引入jar包依赖:

  • implementation'com.github.xiaoymin:knife4j-spring-boot-starter:2.0.9'
  • implementation'io.springfox:springfox-boot-starter:3.0.0'
  • 创建SwaggerConfiguration

  • @Configuration
  • @EnableSwagger2
  • @EnableKnife4j
  • publicclassSwaggerConfiguration{
  • @Bean
  • publicDocketgroupRestApi(){
  • returnnewDocket(DocumentationType.SWAGGER_2).groupName("teamsys-service")
  • .select()
  • .apis(RequestHandlerSelectors.basePackage("com.mlz.teamsys"))
  • .paths(PathSelectors.any())
  • .build()
  • .apiInfo(groupApiInfo());
  • }
  • privateApiInfogroupApiInfo(){
  • returnnewApiInfoBuilder().title("鹏云班组-系统管理").description("鹏云班组-系统管理-接口文档").version("1.1.0").build();
  • }
  • }
  • 注意:之前引入swagger的的依赖需要删除,否则会引起jar包冲突

    2、网关模块聚合业务模块的swagger文档

    引入jar包依赖:

    implementation'com.github.xiaoymin:knife4j-spring-boot-starter:2.0.9'

    重写SwaggerResourcesProvider获取路由资源:

  • /**
  • *@Description:在网关中查询路由信息,生成对应的资源信息
  • *
  • *@AuthorHJW
  • *@Date2022/9/30
  • *@VersionV1.0
  • **/
  • @Component
  • @Primary
  • publicclassMySwaggerResourceProviderimplementsSwaggerResourcesProvider{
  • /**
  • *RouteLocator,GatewayProperties这两个类都是springcloud提供的springbean对象直接注入即可
  • */
  • privatefinalRouteLocatorrouteLocator;
  • /**
  • *gateway配置文件
  • */
  • privatefinalGatewayPropertiesgatewayProperties;
  • @Override
  • publicList<SwaggerResource>get(){
  • List<SwaggerResource>resources=newArrayList<>();
  • List<String>routes=newArrayList<>();
  • routeLocator.getRoutes().subscribe(route->routes.add(route.getId()));
  • //从配置文件中获取并配置SwaggerResource
  • gatewayProperties.getRoutes().stream()
  • //过滤路由
  • .filter(routeDefinition->routes.contains(routeDefinition.getId()))
  • //循环添加,从路由的断言中获取,一般来说路由都会配置断言Path信息,这就不多说了
  • .forEach(route->{
  • route.getPredicates().stream()
  • //获取Path信息
  • .filter(predicateDefinition->("Path").equalsIgnoreCase(predicateDefinition.getName()))
  • //开始添加SwaggerResource
  • .forEach(predicateDefinition->resources.add(swaggerResource(route.getId(),
  • predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX"0")
  • .replace("**","v2/api-docs?group="route.getId()))));
  • });
  • returnresources;
  • }
  • privateSwaggerResourceswaggerResource(Stringname,Stringlocation){
  • SwaggerResourceswaggerResource=newSwaggerResource();
  • swaggerResource.setName(name);
  • swaggerResource.setLocation(location);
  • swaggerResource.setSwaggerVersion("2.0");
  • returnswaggerResource;
  • }
  • @Autowired
  • publicMySwaggerResourceProvider(RouteLocatorrouteLocator,GatewayPropertiesgatewayProperties){
  • this.routeLocator=routeLocator;
  • this.gatewayProperties=gatewayProperties;
  • }
  • }
  • 重写swagger-resources的访问接口:

  • /**
  • *@Description:swagger资源信息
  • *
  • *@AuthorHJW
  • *@Date2022/9/30
  • *@VersionV1.0
  • **/
  • @RestController
  • @RequestMapping("/swagger-resources")
  • @RequiredArgsConstructor
  • publicclassSwaggerResourceController{
  • privatefinalMySwaggerResourceProviderswaggerResourceProvider;
  • @RequestMapping
  • publicResponseEntity<List<SwaggerResource>>swaggerResources(){
  • returnnewResponseEntity<>(swaggerResourceProvider.get(),HttpStatus.OK);
  • }
  • }
  • 添加请求头过滤器:

  • @Component
  • publicclassSwaggerHeaderFilterextendsAbstractGatewayFilterFactory{
  • privatestaticfinalStringHEADER_NAME="X-Forwarded-Prefix";
  • privatestaticfinalStringURI="/v2/api-docs";
  • @Override
  • publicGatewayFilterapply(Objectconfig){
  • return(exchange,chain)->{
  • ServerHttpRequestrequest=exchange.getRequest();
  • Stringpath=request.getURI().getPath();
  • if(!StringUtils.endsWithIgnoreCase(path,URI)){
  • returnchain.filter(exchange);
  • }
  • ServerHttpRequestnewRequest=request.mutate().path(URI).header(HEADER_NAME).build();
  • ServerWebExchangenewExchange=exchange.mutate().request(newRequest).build();
  • returnchain.filter(newExchange);
  • };
  • }
  • }
  • yml文件添加过滤器配置

  • spring:
  • cloud:
  • gateway:
  • routes:
  • -id:xxx-service
  • uri:lb://xxx-service
  • predicates:
  • -Path=/xxx/**
  • filters:
  • -SwaggerHeaderFilter
  • 发表评论

    • 评论列表
    还没有人评论,快来抢沙发吧~