栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

springcloud:gateway聚合swagger 下篇(十二)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

springcloud:gateway聚合swagger 下篇(十二)

0. 引言

上一章我们之前讲解了在单个服务中部署swagger,但每次都需要在不同的端口中访问不同服务的swagger-ui。那么本期我们就来讲解一下,如何从一个统一的入口访问不同服务的swagger

1. 思路

我们之前讲过网关的概念,如果不清楚的可以查看之前的博文。那么想象一下,我们是不是可以从一个统一的入口访问接口文档,然后通过路由转发将实际请求转发到对应的微服务上

如果看过之前讲网关gateway这篇内容的同学,听到这里是不是有点思路了?这不就是网关路由转发吗?统一的入口就是网关的入口。再根据服务名转发到不同的微服务中的swagger-ui。

那么我们就可以把网关作为统一入口,同时也在网关服务中配置上swagger,将网关作为swagger-server。各个微服务中也部署各自的单机版的swagger,作为swagger-client。之后会通过路由转发将对swagger的请求转发到各个微服务中。

1.1 什么是 v2/api-docs?

在开始具体实现之前,先要给大家说明几个概念,帮助大家理解后续的代码。首先我们的swagger文档信息实际上是通过v2/api-docs这个接口获取的,这个接口是swagger自带的。

我们可以调用一个微服务的v2/api-docs接口试试:

会发现他返回的json数据,就是我们要在页面中展示的接口文档数据。所以我们通过网关来实现swagger的接口转发,实际上转发的就是v2/api-docs接口

1.2 什么是swagger-resources?

这也是一个接口地址,默认这个接口获取的是本服务的api-docs访问路径,我们可以通过重写这个接口实现获取到所有微服务的api-docs访问路径。

本机服务的swagger-resources接口调用

网关中重写后的swagger-resources接口调用

具体针对这个接口的实现,我们在下面的的实操中讲解

2. 完整实现

1、在各微服务中部署单机版swagger,不清楚怎么部署的请看上一篇:
接口文档自动生成器swagger详解 上篇

之后的操作均在网关服务中进行!!!

2、网关服务中引入依赖

目前swagger官方已经更新到了swagger3了,但是大多数开发中仍然在使用swagger2,所以我们这里使用swagger2

        

            io.springfox
            springfox-swagger2
            2.9.2

        

            io.springfox
            springfox-swagger-ui
            2.9.2

3、创建swagger配置文件SwaggerConfig,该类主要用于提供两个bean: securityConfiguration和uiConfiguration。这两个bean在后续会被调用

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.swagger.web.SecurityConfiguration;
import springfox.documentation.swagger.web.SecurityConfigurationBuilder;
import springfox.documentation.swagger.web.UiConfiguration;
import springfox.documentation.swagger.web.UiConfigurationBuilder;


@Configuration
public class SwaggerConfig {

    @Bean
    public SecurityConfiguration securityConfiguration(){
        return SecurityConfigurationBuilder.builder().build();
    }

    @Bean
    public UiConfiguration uiConfiguration(){
        return UiConfigurationBuilder.builder().build();
    }

}

4、再创建swagger的数据资源类,这个类主要用于提供swagger各种资源。

在访问swagger-ui.html页面的时候,主要就是通过访问以下接口来获取文档数据

import lombok.AllArgsConstructor; 
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
import springfox.documentation.swagger.web.*;

import java.util.List;
import java.util.Optional;


@RestController
@RequestMapping("/swagger-resources")
@AllArgsConstructor
public class SwaggerHandler {

    private final SecurityConfiguration securityConfiguration;
    private final UiConfiguration uiConfiguration;
    private final SwaggerResourcesProvider swaggerResourcesProvider;

    @GetMapping("/configuration/security")
    public Mono> securityConfiguration(){
        return Mono.just(new ResponseEntity<>(
                Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()), HttpStatus.OK));
    }

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

    @GetMapping
    public Mono>> swaggerResources(){
        return Mono.just((new ResponseEntity<>(swaggerResourcesProvider.get(),HttpStatus.OK)));
    }
}

5、创建swagger资源配置类,该类主要用于聚合其他微服务中Swagger的api-docs访问路径

import lombok.AllArgsConstructor;
import org.springframework.cloud.gateway.config.GatewayProperties;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.support.NameUtils;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;

import java.util.*;


@Primary
@Component
@AllArgsConstructor
public class Swagger2ResourceProvider implements SwaggerResourcesProvider {

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

    @Override
    public List get() {
        List resources = new ArrayList<>();
        List 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()
                        // 忽略配置文件中断言中配置的Path为空的配置项
                        .filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName()))
                        // 将Path中的路由地址由**改为v2/api-docs,swagger就是通过这个地址来获取接口文档数据的,可以通过访问:ip:port/v2/api-docs来体会接口数据
                        .forEach(predicateDefinition -> resources
                                .add(swaggerResource(route.getId(), predicateDefinition.getArgs()
                                        .get(NameUtils.GENERATED_NAME_PREFIX + "0").replace("**", 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;
    }
}

6、修改网关配置文件,将需要聚合swagger的微服务路由配置上

spring:
  cloud:
      routes:
        # id 显示到页面上的名称
        - id: 商品服务 product-server
        #   lb://xxx, xxx为服务名
          uri: lb://product-server
          predicates:
        # Path=/xxxv2/api-docs","swagger-ui.html","swagger-resourcesv2/api-docs","swagger-ui.html","swagger-resources
@Component
public class TokenFilter implements GlobalFilter, Ordered{

    private final String[] skipAuthUrls = new String[]{"/login/check","/user/register",
            "v2/api-docs","swagger-ui.html","swagger-resources
    public boolean isSkipUrl(String url) {
        if(StringUtils.isEmpty(url)){
            return false;
        }
        AntPathMatcher matcher = new AntPathMatcher();
        for (String skipAuthUrl : skipAuthUrls) {
            if(matcher.match(skipAuthUrl, url)){
                return true;
            }
        }
        return false;
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

8、启动gateway及其他添加了swagger的微服务

9、访问:http://localhost/swagger-ui.html

如图所示,我们可以在右上角切换文档服务。至此我们的gateway聚合swagger就配置完成了。

当然我们还可以把swagger的配置封装成一个工具服务,只需要引入这个服务,就不用再单独配置了,这一点大家可以先尝试看看,我们会在后续的讲解中演示

演示代码地址

gateway聚合swagger代码

关注公众号 Elasticsearch之家,了解更多新鲜内容
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/826240.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号