Spring Cloud Gateway集成聚合型Spring Boot API发布组件knife4j,增强Swagger

news2024/11/29 0:45:01

大家都知道,在前后端分离开发的时代,前后端接口对接是一项必不可少的工作。

可是,为后端开发,怎么和前端更好的配合,才能让自己不心累、脑累,直接扔给前端一个后端开放api接口文档或者页面,让前端不用看着难受,也不用前端老问你,来愉快的合作呢?

原来可能我们一直用的是Swagger,不得不说Swagger是一个非常好的框架,自从它的出现,大大减少了我们对接的繁重工作。(以前我们开发可是经常要写开发接口文档的)

可是我们在用Swagger时,不管是Swagger本身,还是SwaggerUI,用起来其实不是那么的便捷,尤其是SwaggerUI,反正我用起来真的很是难受,也许是因为它不是我们国人开发的,所以操作方面根本没有我们国人的操作习惯设计。

幸好啊,我们国人也是很厉害的。

Knife4j这个东东,简直是及时雨,用起来丝滑的很。看看它的界面,是不是就是国人的思维设计?

有了这个东东,那么我们来研究一下,怎么让他来集成我们的Gateway,那么如何实现Gateway,可以查看我的上一篇文章。

轻量级的Spring Cloud Gateway实践,实现api和websocket转发icon-default.png?t=N7T8https://blog.csdn.net/t610654893/article/details/137783310?spm=1001.2014.3001.5501

那么,我在这个项目基础上,实现Knife4j的集成实现。

首先,我来说一下我的整体项目结构:

--- 俩个主要的Spring Boot名
【app-server】前端接口服务
【manager-server】后端管理平台服务器接口
--- 微服网关、配置等平台服务
【cloud-server】
---【gateway-starter】路由套件 
--- 等等
【common-server】公共starter目录的服务
---【boot-starter】公共套件 
--- 等等

好,那么我们先从gateway着手来实现。首先pom.xml内引入:

<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-spring-boot-starter</artifactId>
    <version>3.0.3</version>
</dependency>

在Gateway项目内,新增一个类集成SwaggerResourcesProvider配置SwaggerProvider,获取Api-doc!

/**
 * <b>功能:</b>SWAGGER聚合服务<br>
 */
@Slf4j
@Component
@Primary
@AllArgsConstructor
public class SwaggerResourceConfig implements SwaggerResourcesProvider {

    @Resource
    private Environment env;

    private final RouteLocator routeLocator;
    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()));
        gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId())).forEach(route -> {
            route.getPredicates().stream()
                    .filter(predicateDefinition ->
                            ("Path").equalsIgnoreCase(predicateDefinition.getName()))
                    .forEach(predicateDefinition ->
                            resources.add(swaggerResource(route.getId(),
                                    predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0").replace("**", "v3/api-docs"))));
        });

        return resources;
    }

    private SwaggerResource swaggerResource(String name, String location) {
        log.info("name:{},location:{}", name, location);
        SwaggerResource swaggerResource = new SwaggerResource();
        swaggerResource.setName(env.getProperty(name));
        swaggerResource.setLocation(location + "?group=KN");
        swaggerResource.setSwaggerVersion("3.0.3");
        return swaggerResource;
    }
}

​​​​​为了能更好的实现界面的客观性,我们这里写了一个swaggerResource的方法,此方法主要是为了能更好的表达我们的Api接口是属于谁的。比如说我们在Gateway的配置内配置了:routes[0].id=lb://app-server, 那么我们在配置后再加一个app-server=分组接口,那么在Knife4j内就可以更直观的选择属于app-server的项目API了。

图片

我们这里主要还是你为了集成Swagger的内容,来完成Knife4j的前段实现。

因为Gateway里没有配置SwaggerConfig,而运行Swagger-ui又需要依赖一些接口,所以我们还需要自己来实现swagger-resource端点。

这里其实也很简单,我们再新建一个类,来完成我们对swagger-resource的实现。

/**
 * <b>功能:</b>SWAGGER聚合服务<br>
 */
@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)));
    }

    @GetMapping("/api")
    @SentinelResource("api")
    public Set<ApiDefinition> apiRules() {
        return GatewayApiDefinitionManager.getApiDefinitions();
    }

    @GetMapping("/gateway")
    @SentinelResource("gateway")
    public Set<GatewayFlowRule> apiGateway() {
        return GatewayRuleManager.getRules();
    }

    @GetMapping("/flow")
    @SentinelResource("flow")
    public List<FlowRule> apiFlow() {
        return FlowRuleManager.getRules();
    }
}

Gateway端接口已经配置完成。接下来配置实现客户端,由于我的工程俩个server都引入了boot-server,所以这里我只在boot-server内实现即可。

<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-micro-spring-boot-starter</artifactId>
    <version>3.0.3</version>
</dependency>

客户端服务基本也就是按照Swagger的配置写config即可。这样更加方便我们以Swagger为基础更增强我们的api接口发布。为了更详尽的使用,我们一一实现。

增加Swagger 配置类

@EnableOpenApi
@Configuration
@EnableConfigurationProperties(value = {SwaggerProperties.class})
public class SwaggerConfiguration {

  @Resource
  private SwaggerProperties swaggerProperties;

  @Bean
  public Docket createRestApi() {
      Boolean enable = swaggerProperties.getEnable();
      String tryHost = swaggerProperties.getTryHost();
      return new Docket(DocumentationType.OAS_30)
              .groupName("KN")
              // 定义是否开启swagger,false为关闭,可以通过变量控制
              .enable(enable)
              // 将api的元信息设置为包含在json ResourceListing响应中。
              .apiInfo(apiInfo())
              // 接口调试地址
              .host(tryHost)
              // 选择哪些接口作为swagger的doc发布
              .select()
              .apis(RequestHandlerSelectors.any())
              .paths(PathSelectors.regex("/api/.*"))
              .build();
 }


  /**
   * <b>功能描述:</b>API 页面上半部分展示信息<br>
   * <b>修订记录:</b><br>
   * <li>20201225&nbsp;&nbsp;|&nbsp;&nbsp;田星亮&nbsp;&nbsp;|&nbsp;&nbsp;创建方法</li><br>
   */
  private ApiInfo apiInfo() {
      return new ApiInfoBuilder()
              .title(swaggerProperties.getApplicationName())
              .description(swaggerProperties.getApplicationDescription())
              .termsOfServiceUrl("https://www.kn.com/")
              .contact(new Contact("KN", null, "admin@kn.com"))
              .version(swaggerProperties.getApplicationVersion())
              .build();
  }
}

​​​​​​​这里我们再增强一下,使我们的接口更符合api接口规范,给API头增加名为Token的头,在createRestApi方法Docket实现内增加俩个方法后缀,并付上实现:

.build()
// 授权信息设置,必要的header token等认证信息
.securitySchemes(securitySchemes())
.securityContexts(securityContexts());
 /**
   * <b>功能描述:</b>设置授权信息<br>
   */
  private List<SecurityScheme> securitySchemes() {
      return Collections.singletonList(new ApiKey("token", "token", In.HEADER.toValue()));
  }


  /**
   * <b>功能描述:</b>授权信息全局应用<br>
   */
  private List<SecurityContext> securityContexts() {
      return Collections.singletonList(
              SecurityContext.builder()
                      .securityReferences(Collections.singletonList(new SecurityReference("token", new AuthorizationScope[]{new AuthorizationScope("global", "")})))
                      .build()
      );
  }

​​​​​​​上方内配置项详解,完成灵活调用

@Data
@ConfigurationProperties("swagger")
public class SwaggerProperties {

    /**
     * 是否开启swagger,生产环境一般关闭,所以这里定义一个变量
     */
    private Boolean enable;

    /**
     * 项目应用名
     */
    private String applicationName;

    /**
     * 项目版本信息
     */
    private String applicationVersion;

    /**
     * 项目描述信息
     */
    private String applicationDescription;

    /**
     * 接口调试地址
     */
    private String tryHost;
}

至此,我们配置完成,打开Gateway所属的端口链接即可完成Knife4j的访问。Knife4j的配置内还有一些高级项配置,大家按照自己需要增强哦,比如说api排序这个我就很喜欢。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1603352.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spark/SparkSQL读取Hadoop LZO文件概述

一、前置配置 IDEA Maven安装配置 Scala&#xff08;可选&#xff09; Java Hadoop.dll&#xff08;可能需要&#xff0c;具体看有无相关错误信息&#xff09; hadoop-lzo-0.xx.xx.jar&#xff08;如果你的版本过高&#xff0c;需要到官网下载高版本&#xff0c;mvnrepository仓…

Elasticsearch:如何将 MongoDB 数据引入 Elastic Cloud

作者&#xff1a;Hemendra Singh Lodhi Elastic Cloud 是由 Elastic 提供的基于云的托管服务。Elastic Cloud 允许客户在亚马逊网络服务 (AWS)、谷歌云平台 (GCP) 和微软 Azure 上部署、管理和扩展他们的 Elasticsearch 集群。 MongoDB 是一种流行的 NoSQL 文档导向数据库&am…

(vue)el-select选择框加全选/清空/反选

(vue)el-select选择框加全选/清空/反选 <el-form-item label"批次"><el-selectv-model"formInline.processBatch"multiplecollapse-tagsfilterableplaceholder"请选择"style"width: 250px"no-data-text"请先选择企业、日…

React - 高级用法

React高级用法 Hooks Reducer useReducer&#xff1a; import React, { useReducer, useState } from react;const initialState { count: 0 };function reducer(state, action) {switch (action.type) {case increment:return { count: state.count 1 }case decrement:re…

获取公募基金持仓【数据分析系列博文】

摘要 从指定网址获取公募基金持仓数据&#xff0c;快速解析并存储数据。 &#xff08;该博文针对自由学习者获取数据&#xff1b;而在投顾、基金、证券等公司&#xff0c;通常有Wind、聚源、通联等厂商采购的数据&#xff09; 1. 导入必要的库&#xff1a; pandas 用于数据处理…

「Qt Widget中文示例指南」如何实现行编辑功能

Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写&#xff0c;所有平台无差别运行&#xff0c;更提供了几乎所有开发过程中需要用到的工具。如今&#xff0c;Qt已被运用于超过70个行业、数千家企业&#xff0c;支持数百万设备及应用。 Line Edits&#xf…

后端插入数据库问题

IDEA报错&#xff1a;Error updating database. Cause: java.sql.SQLException: Column count doesn’t match value count at row 1 1、看报错消息&#xff0c;SQLException&#xff0c;定位到SQL语句问题 并且看best guess最好猜测&#xff0c;再去找路径下的ShoppingCartMa…

React-基础语法学习

1、教程&#xff1a;井字棋游戏 本教程将引导你逐步实现一个简单的井字棋游戏&#xff0c;并且不需要你对 React 有任何了解。在此过程中你会学习到一些编写 React 程序的基本知识&#xff0c;完全理解它们可以让你对 React 有比较深入的理解。 1.1、教程分成以下几个部分&am…

Hudi-IDEA编程

项目 一、HudiSparkKafka&#xff08;Scala&#xff09; 配置详见【1.Scala配置】 依赖详见【1.HudiSparkKafka依赖】 1-1 构建SparkSession对象 def main(args: Array[String]): Unit {//1.构建SparkSession对象val spark: SparkSession SparkUtils.createSparkSession(…

社交媒体数据恢复:YY语音

YY语音数据恢复指南 在我们的日常生活中&#xff0c;数据丢失是一种常见的现象。有时候&#xff0c;我们可能会不小心删除了重要的文件&#xff0c;或者因为硬件故障而导致数据丢失。在这种情况下&#xff0c;数据恢复软件可以帮助我们找回丢失的数据。本文将重点介绍如何使用Y…

手机拍照技术

拍照技巧 说明: 本文将主要介绍摄影和手机常见技巧&#xff1b; 1. 摄影的基本知识 **说明&#xff1a;**关于摄影&#xff0c;手机和相机的原理都是相同的&#xff0c;不同的是相机在很多方面优于手机&#xff0c;但是专业的设备对于我们这种的非专业的人来说&#xff0c;刚…

MAC上如何将某个目录制作成iso格式磁盘文件,iso文件本质是什么?以及挂载到ParallelDesktop中?(hdiutil makehybrid )

背景 ParallelsDesktop没有安装ParallelsTools的无法共享目录&#xff0c;可以通过ParallelsDesktop提供CD磁盘的方式共享进去 命令 # 准备文档 mkdir mytestdir cp xxx mytestdir# 生成iso hdiutil makehybrid -o output.iso mytestdir -iso -joliethdiutil是MAC提供的磁盘…

linux 修改 root 密码

1、先重启 2、看到下面的界面&#xff0c;按上下箭头&#xff0c;然后按 e 键。 3、进入该界面&#xff0c;按界面步骤操作 4、按ctrlx&#xff0c;进入到下面的界面&#xff0c;依次输入下面的指令即可 mount -o remount,rw /sysroot #让sysroot 能读写chroot /sysroot #切换到…

校园综合服务平台V3.9.2 源码修复大部分已知BUG

校园综合服务平台&#xff0c;版本更新至V3.9.1 &#xff0c;源码功能强大&#xff0c;ui 精美&#xff0c; 功能包含但不限于校园跑腿&#xff0c;外卖&#xff0c;组局&#xff0c;圈子&#xff0c;商城&#xff0c;抽奖&#xff0c;投票&#xff0c;团购&#xff0c;二手市场…

Python中2种常用数据可视化库:Bokeh和Altair

本文分享自华为云社区《探究数据可视化&#xff1a;Bokeh vs. Altair》&#xff0c;作者&#xff1a;柠檬味拥抱。 在数据科学和数据分析领域&#xff0c;数据可视化是一种强大的工具&#xff0c;可以帮助我们更好地理解数据、发现模式和趋势。Python作为一种流行的数据科学工…

【QT进阶】Qt Web混合编程之QWebEngineView基本用法

往期回顾 【QT入门】Qt自定义控件与样式设计之自定义QTabWidget实现tab在左&#xff0c;文本水平的效果-CSDN博客【QT进阶】Qt Web混合编程之CEF、QCefView简单介绍-CSDN博客 【QT进阶】Qt Web混合编程之VS2019 CEF的编译与使用-CSDN博客 【QT进阶】Qt Web混合编程之QWebEngi…

(十四)C++自制植物大战僵尸游戏windows平台视频播放实现

植物大战僵尸游戏开发教程专栏地址http://t.csdnimg.cn/8UFMs VLC库 在Cocos2d-x游戏开发框架中&#xff0c;没有实现windows平台视频播放的功能&#xff0c;需要自定义实现。在本项目中使用vlc库实现windows平台的视频播放功能。 vlc官网&#xff1a;网址 下载完成后&#x…

.net反射(Reflection)

文章目录 一.概念&#xff1a;二.反射的作用&#xff1a;三.代码案例&#xff1a;四.运行结果&#xff1a; 一.概念&#xff1a; .NET 反射&#xff08;Reflection&#xff09;是指在运行时动态地检查、访问和修改程序集中的类型、成员和对象的能力。通过反射&#xff0c;你可…

分布式搭载博客网站

一.运行环境&#xff1a; IP主机名系统服务192.168.118.128Server-WebLinuxWeb192.168.118.131Server-NFS-DNSLinuxNFS/DNS 二.基础配置 1. 配置主机名&#xff0c;hosts映射 [rootserver ~]# hostnamectl set-hostname Server-Web [rootserver ~]# hostname Server-Web [r…

每日算法4/17

1552. 两球之间的磁力 题目 在代号为 C-137 的地球上&#xff0c;Rick 发现如果他将两个球放在他新发明的篮子里&#xff0c;它们之间会形成特殊形式的磁力。Rick 有 n 个空的篮子&#xff0c;第 i 个篮子的位置在 position[i] &#xff0c;Morty 想把 m 个球放到这些篮子里&…