IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> SpringCloud微服务项目的api文档聚合 -> 正文阅读

[Java知识库]SpringCloud微服务项目的api文档聚合

本文简单介绍在Spring Cloud Gateway项目里聚合多个微服务的swagger文档的实践经验。

在聚合各个微服务的api文档之前,您自然已经搭建好了微服务开发的框架,所以各个微服务项目里的服务注册与发现应该都已经配置好了。Swagger框架可以选用Springfox或Springdoc

原理简介

我们知道Swagger或着说后来的openApi是一种描述api接口文档的规范。每个使用了swagger的项目,在/v2/api-docs或/v3/api-docs路径下都可以看到该项目所有的接口描述。但是由于每个微服务的项目部署的ip地址和端口都不一样,所以需要分别访问每个项目的文档路径才能看到相应的地址,这是不方便的。现在我们使用了网关,而网关又有请求转发的功能,所以我们可以在网关的项目里,手动设置各个微服务swagger文档的资源路径,只是ip地址和端口都变成网关微服务的了。然后当我们向网关请求某个微服务api文档的路径时,网关会自动转发到对应的服务上。

在网关中配置好路由

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #开启网关的服务发现
      routes:
        - id: 配置路由id
          uri: lb://微服务名 #注意这里的格式
          order: -1
          predicates:
            - 
          filters:
            - 

Spring Cloud Gatway + Springfox

文档地址:http://springfox.github.io/springfox/docs/current/

第一步、在各项目里配置Springfox

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-boot-starter</artifactId>
    <version>3.0.0</version>
</dependency>

使用Swaager2和Swagger3时,这两个地方设置不一样使用Swaager2和Swagger3时,这两个地方设置不一样。

第二步、在网关中编写api文档资源路径

package cn.com.nbd.app.gateway.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;


import java.util.ArrayList;
import java.util.List;

/**
 * <p>描述:</p>
 *
 * @author 木刀
 * @since 2022/3/17 15:57
 */
@Component
@Primary
//springfox提供了一个接口SwaggerResourcesProvider,用户可自行编写api资源,这正是我们需要的。
public class GatewaySwaggerResourcesProvider implements SwaggerResourcesProvider {
    public static final String API_URI = "/v3/api-docs"; //swagger2对应的是/v2/api-docs
    @Value("${spring.application.name}")
    private String gatewayApplicationName;
    @Autowired
    private RouteLocator routeLocator;

    @Override
    public List<SwaggerResource> get() {
        //保存我们手动设置的api文档资源信息
        List<SwaggerResource> resources = new ArrayList<>();
        //取出gateway的route
        routeLocator.getRoutes()
        //将除了网关外的其他微服务对应的路由筛选出来
                .filter(route -> route.getUri().getHost() != null
                        && !gatewayApplicationName.equals(route.getUri().getHost())
                        && !route.getId().startsWith("ReactiveCompositeDiscoveryClient")
                        )
                .subscribe(route -> {
                //获取对应路由的servlet.context-path
                    contextPath = route.getUri().getHost();
                    //拼接对应微服务的api文档路径,每个微服务对应一个SwaggerResource,但这里的路径的ip地址和端口是网关的,所以我们在网关的swagger-ui中可以看到。然后由网关转发到对应的微服务地址去。
                    resources.add(swaggerResource(route.getId(),
                            "/" + contextPath + API_URI));
                });
        return resources;
    }

    private SwaggerResource swaggerResource(String name, String url) {
        SwaggerResource swaggerResource = new SwaggerResource();
        swaggerResource.setName(name);
        swaggerResource.setUrl(url);
        swaggerResource.setSwaggerVersion("3.0");
        return swaggerResource;
    }
}

注意

  • 截止2022/4/3,spring boot 2.6以上的版本使用springfox会出现问题
    spring boot 2.6以上版本+spingfox 3.0会出现一个问题,
    Failed to start bean ‘documentationPluginsBootstrapper’; nested exception is java.lang.NullPointerException
    目前还没有解决办法,有成功解决的希望可以分享在评论里。
  • swagger 3.0不需要为每个路由配置过滤器StripPrefix=1,否则会出现:Fetch errorNot Found

Spring Cloud Gatway + Springdoc

文档地址:https://springdoc.org/

第一步、引入依赖

在网关项目里引入:

<dependency>
			<groupId>org.springdoc</groupId>
			<artifactId>springdoc-openapi-webflux-ui</artifactId>
			<version>1.6.6</version>
		</dependency>

在其他项目里:

如果是servlet:
<dependency>
			<groupId>org.springdoc</groupId>
			<artifactId>springdoc-openapi-webmvc-core</artifactId>
			<version>1.6.6</version>
		</dependency>

如果的webflux:
<dependency>
			<groupId>org.springdoc</groupId>
			<artifactId>springdoc-openapi-webflux-core</artifactId>
			<version>1.6.6</version>
		</dependency>

第二步、手动配置api文档路径

/**
 * <p>描述:</p>
 *
 * @author 木刀
 * @since 2022/4/1 13:28
 */
@Configuration
public class SpringDocConfig {
    @Bean
    @Lazy(false)
    public List<GroupedOpenApi> apis(SwaggerUiConfigParameters swaggerUiConfigParameters, RouteDefinitionLocator locator) {
        List<GroupedOpenApi> groups = new ArrayList<>();
        //仍然是通过路由定义获取context-path
        locator.getRouteDefinitions()
                .filter(route -> route.getUri().getHost() != null
                        && !gatewayApplicationName.equals(route.getUri().getHost())
                        && !route.getId().startsWith("ReactiveCompositeDiscoveryClient")
                        )
                .subscribe(routeDefinition -> {
                    contextPath = route.getUri().getHost();
                    swaggerUiConfigParameters.addGroup(name);
                    groups.add(GroupedOpenApi.builder()
                            .pathsToMatch("/" + contextPath + "/**")
                            .group(name)
                            .build());
                });

        return groups;
    }

第三步、使用重写路径过滤器转换路径

springdoc中,我们手动设置的aip文档路径最后生成的格式为/v3/api-docs/{contextPath},所以我们需要把他转换成:/{contextPath}/v3/api-docs,可以借助网关中的路径重写过滤器。

- id: openapi
          uri: http://localhost:${server.port}
          order: -2 #该路由的优先级最后高于其他微服务的路由
          predicates:
            - Path=/v3/api-docs/**
          filters:
            - RewritePath=/v3/api-docs/(?<path>.*), /$\{path}/v3/api-docs
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-04-04 11:57:16  更:2022-04-04 12:01:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:28:22-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码