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

一、背景

        项目开发中前后端衔接有多种工具,我们选用的是swagger,一个版本下来复盘的时候项目组成员反馈不好用,接口难找,页面也很不美观;于是寻找集成的方式将微服务多个项目集成到一起,最终选择spring cloud gateWay + knife4j方案,因为我们网关用的是spring cloud gateWay,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
public class SwaggerConfiguration {
    @Bean
    public Docket groupRestApi() {
        return new Docket(DocumentationType.SWAGGER_2).groupName("teamsys-service")
            .select()
            .apis(RequestHandlerSelectors.basePackage("com.mlz.teamsys"))
            .paths(PathSelectors.any())
            .build()
            .apiInfo(groupApiInfo());
    }

    private ApiInfo groupApiInfo() {
        return new ApiInfoBuilder().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: 在网关中查询路由信息,生成对应的资源信息
 *
 * @Author HJW
 * @Date 2022/9/30
 * @Version V1.0
 **/
@Component
@Primary
public class MySwaggerResourceProvider implements SwaggerResourcesProvider {
    /**
     * RouteLocator,GatewayProperties这两个类都是springcloud提供的springbean对象直接注入即可
     */
    private final RouteLocator routeLocator;

    /**
     * gateway配置文件
     */
    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()));
        // 从配置文件中获取并配置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()))));
            });

        return resources;
    }

    private SwaggerResource swaggerResource(String name, String location) {
        SwaggerResource swaggerResource = new SwaggerResource();
        swaggerResource.setName(name);
        swaggerResource.setLocation(location);
        swaggerResource.setSwaggerVersion("2.0");
        return swaggerResource;
    }

    @Autowired
    public MySwaggerResourceProvider(RouteLocator routeLocator, GatewayProperties gatewayProperties) {
        this.routeLocator = routeLocator;
        this.gatewayProperties = gatewayProperties;
    }

}

          重写swagger-resources的访问接口:

/**
 * @Description: swagger 资源信息
 *
 * @Author HJW
 * @Date 2022/9/30 
 * @Version V1.0
 **/
@RestController
@RequestMapping("/swagger-resources")
@RequiredArgsConstructor
public class SwaggerResourceController {
    private final MySwaggerResourceProvider swaggerResourceProvider;

    @RequestMapping
    public ResponseEntity<List<SwaggerResource>> swaggerResources() {
        return new ResponseEntity<>(swaggerResourceProvider.get(), HttpStatus.OK);
    }
}

         添加请求头过滤器:

@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);
            }
            ServerHttpRequest newRequest = request.mutate().path(URI).header(HEADER_NAME).build();
            ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();
            return chain.filter(newExchange);
        };
    }
}

        yml文件添加过滤器配置

spring:
  cloud:
    gateway:
      routes:
        - id: xxx-service
          uri: lb://xxx-service
          predicates:
            - Path=/xxx/**
          filters:
            - SwaggerHeaderFilter

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值