【使用gateway+nacos+swagger集成微服务接口文档】

概要

现在相信大部分公司的系统架构都是分布式,微服务 ,在使用swagger文档时,前后端联调或者测试接口每次都要打开各个微服务的文档去找对应的接口比较麻烦,在这里给大家讲讲如何在gateway中集成各个服务的接口文档

整体技术方案

使用gateway+nacos+swagger集成微服务接口文档

实现步骤

  • 业务服务集成swagger文档
@Configuration
@EnableSwagger2WebMvc
public class Knife4jConfiguration {

    @Bean(value = "defaultApi2")
    public Docket defaultApi2() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(new ApiInfoBuilder()
                        //.title("swagger-bootstrap-ui-demo RESTful APIs")
                        .description("# swagger-bootstrap-ui-demo RESTful APIs")
                        .termsOfServiceUrl("http://www.xx.com/")
                        .contact("xx@qq.com")
                        .version("1.0")
                        .build())
                .select()
                //这里指定Controller扫描包路径
                .apis(RequestHandlerSelectors.basePackage("asset.product.api"))
                .paths(PathSelectors.any())
                .build();
    }
}
  • 使用nacos注册服务
  cloud:
    nacos:
      server-addr: xx.xx.x.xx:30887
      config:
        namespace: xx.xx.x.xx
        group: ${spring.application.name}
        refresh-enabled: true
        file-extension: yml
      discovery:
        namespace: xx.xx.x.xx
        group: ${spring.profiles.active}
        register-enabled: true
  • 配置gateway路由
# 基本配置
server:
  servlet:
    context-path: /api/asset-gateway
spring:
  application:
    name: asset-gateway
  profiles:
    active: dev
  jackson:
    time-zone: GMT+8
  cloud:
    gateway:
      discovery:
        locator:
          lower-case-service-id: true
      routes:
        #交易服务
        - id: asset-transaction-svc
          uri: lb://asset-transaction-svc
          predicates:
            - Path=/api/asset-transaction-svc/**
          filters:
            - SwaggerHeaderFilter
        #产品服务
        - id: asset-product-svc
          uri: lb://asset-product-svc
          predicates:
            - Path=/api/asset-product-svc/**
          filters:
            - SwaggerHeaderFilter
        #客户管理服务
        - id: asset-client-management
          uri: lb://asset-client-management
          predicates:
            - Path=/api/asset-client-management/**
          filters:
            - SwaggerHeaderFilter
        #公共服务
        - id: asset-public-svc
          uri: lb://asset-public-svc
          predicates:
            - Path=/api/asset-public-svc/**
          filters:
            - SwaggerHeaderFilter
        #流程引擎
        - id: asset-svc-activiti
          uri: lb://asset-svc-activiti
          predicates:
            - Path=/api/asset-svc-activiti/**
          filters:
            - SwaggerHeaderFilter
  • 重写swagger
@RestController
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("/swagger-resources/configuration/security")
    public Mono<ResponseEntity<SecurityConfiguration>> securityConfiguration() {
        return Mono.just(new ResponseEntity<>(Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()), HttpStatus.OK));
    }

    @GetMapping("/swagger-resources/configuration/ui")
    public Mono<ResponseEntity<UiConfiguration>> uiConfiguration() {
        return Mono.just(new ResponseEntity<>(Optional.ofNullable(uiConfiguration).orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK));
    }

    @GetMapping("/swagger-resources")
    public Mono<ResponseEntity> swaggerResources() {
        return Mono.just((new ResponseEntity<>(swaggerResources.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);
            }
            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);
        };
    }
}
@Component
@Primary
public class SwaggerResourceConfig 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()))
                // 循环添加,从路由的断言中获取
                .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"))));
                });
        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 SwaggerResourceConfig(RouteLocator routeLocator, GatewayProperties gatewayProperties) {
        this.routeLocator = routeLocator;
        this.gatewayProperties = gatewayProperties;
    }
}
  • 打开文档
    http://localhost:8081/doc.html

需要用到的jar

        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-spring-boot-starter</artifactId>
            <version>2.0.7</version>
        </dependency>
                <!-- nacos注册中心 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>2.2.9.RELEASE</version>
        </dependency>
        <!-- nacos配置中心 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            <version>2.2.9.RELEASE</version>
        </dependency>
        <!--gateway-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>
  • 22
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值