gateway 集成 swagger 的详细教程

pom

gateway项目的依赖

本着依赖整洁的原则,我加的是这些:

	<!--swagger-->
	<dependency>
	    <groupId>com.spring4all</groupId>
	    <artifactId>swagger-spring-boot-starter</artifactId>
	    <version>1.9.1.RELEASE</version>
	</dependency>
	
	<!-- 注册中心的依赖 -->
	<dependency>
		<groupId>com.alibaba.cloud</groupId>
		<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
	</dependency>
	
	<!-- 网关依赖  -  此处不能加 spring boot web 依赖,会报错-->
     <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-gateway</artifactId>
     </dependency>

被代理的服务需要的操作:

在启动类上加上 @EnableSwagger2 这个注解

然后也引入下边的依赖:

	<!--swagger-->
	<dependency>
	    <groupId>com.spring4all</groupId>
	    <artifactId>swagger-spring-boot-starter</artifactId>
	    <version>1.9.1.RELEASE</version>
	</dependency>



配置类

这里是重头戏,一共有三个配置类

/**
 * @introduce: Swagger处理器
 * @author: lk
 * @date: 2020/6/4
 **/
@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)));
    }
}
/**
 * @introduce: swagger请求头过滤器
 * @author: lk
 * @date: 2020/6/4
 **/
@Component
public class SwaggerHeaderFilter extends AbstractGatewayFilterFactory {

    private static final String HEADER_NAME = "X-Forwarded-Prefix";

    @Override
    public GatewayFilter apply(Object config) {
        return (exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest();
            String path = request.getURI().getPath();
            if (!StringUtils.endsWithIgnoreCase(path, SwaggerProvider.API_URI)) {
                return chain.filter(exchange);
            }
            String basePath = path.substring(0, path.lastIndexOf(SwaggerProvider.API_URI));
            ServerHttpRequest newRequest = request.mutate().header(HEADER_NAME, basePath).build();
            ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();
            return chain.filter(newExchange);
        };
    }
}
/**
 * @introduce: SwaggerProvider
 * @author: lk
 * @date: 2020/6/4
 **/
@Component
@Primary
@AllArgsConstructor
public class SwaggerProvider implements SwaggerResourcesProvider {

    public static final String API_URI = "/v2/api-docs";
    private final RouteLocator routeLocator;
    private final GatewayProperties gatewayProperties;


    @Override
    public List<SwaggerResource> get() {
        List<SwaggerResource> resources = new ArrayList<>();
        List<String> routes = new ArrayList<>();
        //取出gateway的route
        routeLocator.getRoutes().subscribe(route -> routes.add(route.getId()));
        //结合配置的route-路径(Path),和route过滤,只获取有效的route节点
        gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId()))
                .forEach(routeDefinition -> routeDefinition.getPredicates().stream()
                        .filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName()))
                        .forEach(predicateDefinition -> resources.add(swaggerResource(routeDefinition.getId(),
                                "/"+routeDefinition.getId()+API_URI ))));
        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;

    }
}



yml

spring:
  application:
    name: gateway # 服务名称
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 # 注册中心地址  # 默认是没有密码的
    gateway:
      discovery:
        locator:
          enabled: true  #表明gateway开启服务注册和发现的功能, 动态路由
          lowerCaseServiceId: true
          filters:
      routes:
        - id: test # 唯一id ,随便起,不能重复
          uri: lb://test # 匹配注册中心的服务
          predicates:
            - Path=/test/** # 匹配的规则
          filters:
            # 去掉路由前缀,访问 localhost:8088/test/v2/api 转发的就是 localhost:8089/v2/api
            # 1 : 代表剥离路径的个数
            - StripPrefix=1

特别注意:

filters:
-StripPrefix=1

这个一定不要去掉,不然你就访问不到你服务的swagger,如下图
在这里插入图片描述



结果

这样配置一下以后,就可以成功的通过 gateway 的地址访问 各个微服务的swagger了,如下图:
在这里插入图片描述

巨人的肩膀:
1、全网首例Spring Cloud Gateway整合Swagger2 Demo
2、springcloud-gateway网关聚合swagger实现多个服务接口切换
3、spring cloud gateway聚合swagger的方法记录



看似简单,实则鼓捣了半天,亲测没问题,如果大家遇到了什么问题,欢迎评论提出,我们一起讨论!

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值