SpringCloud网关聚合knife4j方案

news2024/11/23 21:05:09

微服务开发中想将Spring-Cloud-Gateway网关聚合knife4j,形成一个统一入口方便查阅的开发辅助接口文档,并且将Swagger抽取成一个公共模块,那么我们可以参考以下的做法

约定:

Java Version:11.0.24

Spring Boot:2.7.18

knife4j:4.4.0

Swagger公共模块抽取

依赖

<dependencies>
    <!-- SpringBoot Web (支持构建Web应用程序,包括Spring MVC和内嵌的Servlet容器) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Knife4j API 小刀注解依赖 -->
    <dependency>
        <groupId>com.github.xiaoymin</groupId>
        <artifactId>knife4j-openapi2-spring-boot-starter</artifactId>
    </dependency>

    <dependency>
        <groupId>com.github.xiaoymin</groupId>
        <artifactId>swagger-bootstrap-ui</artifactId>
        <version>1.9.6</version>
    </dependency>

    <!-- SpringBoot Actuator (支持集成Actuator,用于监控和管理应用程序) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    <!-- Java Bean Validation API -->
    <dependency>
        <groupId>javax.validation</groupId>
        <artifactId>validation-api</artifactId>
        <version>2.0.1.Final</version>
    </dependency>

    <!-- Lombok 辅助器 -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

定义配置Swagger Properties

package com.if010.common.swagger.properties;

import lombok.*;
import org.springframework.boot.context.properties.ConfigurationProperties;

import java.io.Serializable;

/**
 * Swagger Properties配置信息实体类
 * @author Kim同学
 */

@Data
@NoArgsConstructor
@ToString
@ConfigurationProperties(prefix = "swagger")
public class SwaggerConfigProperties implements Serializable {

    //配置 API (com.xxx.controller) 扫描路径
    public String controllerPath;

    //配置 API 文档标题
    public String title;

    //配置 API 版本信息
    public String version;

    //配置 API 文档描述
    public String description;

    //配置 API 文档许可 描述 或 协议
    public String license;

    //配置 API 文档许可 描述 或 协议 的 URL
    public String licenseUrl;

    //配置 API 文档 联系人 信息
    public String contactName;

    //配置 API 文档 联系人 主页 URL
    public String contactUrl;

    //配置 API 文档 联系人 邮箱
    public String contactEmail;
}

定义配置Swagger Config

package com.if010.common.swagger.config;

import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import com.if010.common.swagger.properties.SwaggerConfigProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.CorsEndpointProperties;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType;
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
import org.springframework.boot.actuate.endpoint.web.*;
import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointsSupplier;
import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier;
import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils;
import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;

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

/**
 * Swagger 配置类
 * @author Kim同学
 */

@Slf4j
@Configuration
@EnableSwagger2WebMvc
@EnableKnife4j
@ConditionalOnClass({Docket.class, ApiInfoBuilder.class})
@EnableConfigurationProperties(SwaggerConfigProperties.class)
@Import(BeanValidatorPluginsConfiguration.class)
public class SwaggerConfig {

    @Autowired
    SwaggerConfigProperties swaggerConfigProperties;

    private ApiInfo apiInfoBuilder() {
        ApiInfo apiInfoBuild = new ApiInfoBuilder()
                // api文档名称
                .title(swaggerConfigProperties.getTitle())
                // api文档描述
                .description(swaggerConfigProperties.getDescription())
                // api文档版本
                .version(swaggerConfigProperties.getVersion())
                // api作者信息
                .contact(
                        new Contact(
                            swaggerConfigProperties.getContactName(),
                            swaggerConfigProperties.getContactUrl(),
                            swaggerConfigProperties.getContactEmail()
                        )
                )
                // api文档许信息
                .license(swaggerConfigProperties.getLicense())
                // api文档许信息链接
                .licenseUrl(swaggerConfigProperties.getLicenseUrl())
                .build();
        return apiInfoBuild;
    }

    @Bean(value = "defaultApi2")
    @ConditionalOnClass(SwaggerConfigProperties.class)
    public Docket defaultApi2() {
        log.info("swaggerInfo:{}", swaggerConfigProperties.getControllerPath());

        // 构建API文档  文档类型为swagger2
        return new Docket(DocumentationType.SWAGGER_2).select()
            // 配置 API 扫描路径 以及 过滤规则(any代表所有路径)
            .apis(RequestHandlerSelectors.basePackage(swaggerConfigProperties.getControllerPath())).paths(PathSelectors.any())
            // 配置 API 的基本信息
            .build().apiInfo(apiInfoBuilder());
    }

    /**
     * 增加如下配置可解决Spring Boot 6.x 与Swagger 3.0.0 不兼容问题
     **/
    @Bean
    public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpointsSupplier webEndpointsSupplier,
                                                                         ServletEndpointsSupplier servletEndpointsSupplier,
                                                                         ControllerEndpointsSupplier controllerEndpointsSupplier,
                                                                         EndpointMediaTypes endpointMediaTypes,
                                                                         CorsEndpointProperties corsProperties,
                                                                         WebEndpointProperties webEndpointProperties,
                                                                         Environment environment) {
        List<ExposableEndpoint<?>> allEndpoints = new ArrayList();
        Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();
        allEndpoints.addAll(webEndpoints);
        allEndpoints.addAll(servletEndpointsSupplier.getEndpoints());
        allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());
        String basePath = webEndpointProperties.getBasePath();
        EndpointMapping endpointMapping = new EndpointMapping(basePath);
        boolean shouldRegisterLinksMapping = this.shouldRegisterLinksMapping(webEndpointProperties, environment, basePath);
        return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints, endpointMediaTypes, corsProperties.toCorsConfiguration(),
                new EndpointLinksResolver(allEndpoints, basePath), shouldRegisterLinksMapping, null);
    }

    private boolean shouldRegisterLinksMapping(WebEndpointProperties webEndpointProperties, Environment environment, String basePath) {
        return webEndpointProperties.getDiscovery().isEnabled() && (StringUtils.hasText(basePath) || ManagementPortType.get(environment).equals(ManagementPortType.DIFFERENT));
    }
}

因为是starter模块,可能他人的项目目录和starter模块的目录不一致,导致加载不到SwaggerConfig类,我们需要使用spring.factories把SwaggerConfig类装载到Spring容器,在resources/META-INF/spring添加org.springframework.boot.autoconfigure.AutoConfiguration.imports文件

SwaggerAutoConfiguration

到目前为止,Swagger的抽取工作就已经算是全部完成了,接下来我们就可以在业务模块中引入进行测试使用了

引用

首先我们需要将Swagger公共依赖添加到业务模块的pom文件当中

<dependencies>
    <!-- If010 Common Swagger -->
    <dependency>
        <groupId>com.if010</groupId>
        <artifactId>if010-common-swagger</artifactId>
    </dependency>
</dependencies>

接下来,在application.yml定义Swagger的配置信息

swagger:
  # 配置 API 扫描路径
  controllerPath: com.if010.system.controller
  # 配置 API 文档标题
  title: 系统管理模块接口文档
  # 配置 API 版本信息
  version: 1.0.0
  # 配置 API 文档描述
  description: 系统管理模块
  # 配置 API 文档许可 描述
  license: Copyright © 2018 If010工作室™
  # 配置 API 文档许可 描述 URL
  licenseUrl: https://if010.com
  # 配置 API 文档 联系人
  contact-name: Kim同学
  # 配置 API 文档 联系人 主页 URL
  contact-url: www.if010.com
  # 配置 API 文档 联系人 邮箱
  contact-email: kim@if010.com

到此结束,紧接着我们就可以启动业务服务模块,访问:http://{service.host}:{service.port}/doc.html,看看效果啦~~

接口文档页面结果

网关聚合knife4j

依赖

<dependencies>
    # 网关所需要的依赖这里就不进行展示啦,给你们节省一点流量
    .....

    <!-- Knife4j API 小刀注解依赖 -->
    <dependency>
        <groupId>com.github.xiaoymin</groupId>
        <artifactId>knife4j-gateway-spring-boot-starter</artifactId>
    </dependency>
</dependencies>

定义application.yml文件

spring: 
  application:
    # 应用名称
    name: if010-gateway
  profiles:
    # 环境配置
    active: dev
  cloud:
    # Nacos注册中心配置
    nacos:
      # Nacos的认证登录用户账户
      username: admin
      # Nacos的认证登录用户密码
      password: 123456
      discovery:
        # 服务注册地址
        server-addr: 127.0.0.1:8848
      config:
        # 配置中心地址
        server-addr: 127.0.0.1:8848
        # 配置文件格式
        file-extension: yml
        # 共享配置
        shared-configs:
          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
          - application-${spring.profiles.active}-nacos.${spring.cloud.nacos.config.file-extension}
          - ${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
        # 超时时间
        timeout: 3000
    # 路由配置
    gateway:
      routes:
        - id: system-service
          uri: lb://if010-system
          predicates:
            - Path=/system-service/**
          filters:
            # StripPrefix 是 url 过滤器,1表示请求转发给后端业务服务时,去掉上面Path里从左往右的第1个路径,即system-service
            - StripPrefix=1

# knife4j的网关聚合配置 文档地址:http://{gateway.host}:{gateway.port}/doc.html
knife4j:
  # 聚合swagger文档
  gateway:
    # 是否开启Knife4j网关聚合功能(生产环境不建议开启)
    enabled: true
    # 排序规则(tag/operation排序自4.2.0版本新增)
    # 取值:alpha-默认排序规则,官方swagger-ui默认实现,order-Knife4j提供的增强排序规则,开发者可扩展x-order,根据数值来自定义排序
    tags-sorter: order
    operations-sorter: order
    # 指定聚合的策略(默认手动配置(manual),服务发现(discover))
    strategy: manual
    discover:
      # 是否开启服务发现模式的配置
      enabled: false
      # 指定版本号(swagger2|openapi3)
      version: swagger2
      # 需要排除的微服务(eg:网关服务)
      excluded-services:
        - if010-gateway
      # Swagger2个性化配置
      swagger2:
        url: /v2/api-docs?group=default
    # 个性化定制的部分子服务分组情况
    routes:
      - name: 系统管理模块
        # 服务名
        service-name: system-service
        # 真实子服务访问url地址-提供OpenAPI的文档
        url: /system-service/v2/api-docs?group=default
        # 路由前缀,兼容OpenAPI3规范在聚合时丢失contextPath属性的异常情况,由开发者自己配置contextPath,Knife4j的前端Ui做兼容处理,与url属性独立不冲突,仅OpenAPI3规范聚合需要,OpenAPI2规范不需要设置此属性,默认为(apiPathPrefix)
        context-path: /
        # 排序
        order: 1

到此为止,网关聚合knife4j工作就结束了,操作不涉及代码,全都是配置相关,因为个人严重的洁癖问题discover自动发现并没有开启,想省事偷懒的可以开起来,可以大大减少手动配置的工作

访问:http://{gateway.host}:{gateway.port}/doc.html,看看效果啦~~

接口文档页面结果

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

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

相关文章

一探究竟:全能型人体存在传感器如何革新全屋智能生活

如今&#xff0c;全屋智能家居已蔚然成风&#xff0c;亲历过个性化智能家居配置的用户无不深知传感器在其联动逻辑中扮演的关键角色。市场上主流的传感器类型多为移动监测型&#xff0c;此类设备通过探测区域内是否存在人员活动来触发相应的自动化操作。尽管它们在众多应用场景…

实用软件分享

文章路径 Pfolg_Source/实用软件记录.md at main Pfolg/Pfolg_Source (github.com)https://github.com/Pfolg/Pfolg_Source/blob/main/%E5%AE%9E%E7%94%A8%E8%BD%AF%E4%BB%B6%E8%AE%B0%E5%BD%95.md 注 这篇文章水的不得了&#xff0c;但我花了半小时来水……

谷歌-BERT-第四步:模型部署

1 需求 需求1&#xff1a;基于gradio实现大模型的WEB UI交互界面 2 接口 3 示例 import gradio as gr from transformers import *classifier pipeline("text-classification", model"./model", tokenizer"./model")gr.Interface.from_pipel…

c++(多态)

多态的定义 多态是⼀个继承关系的下的类对象&#xff0c;去调⽤同⼀函数&#xff0c;产⽣了不同的⾏为 ⽐如Student继承了Person。Person对象买票全价&#xff0c;Student对象优惠买票。 多态实现的条件 • 必须指针或者引⽤调⽤虚函数 第⼀必须是基类的指针或引⽤&#xff0c;…

【HarmonyOS NEXT】实现二个直角梯形按钮,拼接为矩形,斜边可以点击

【问题描述】 实现二个直角梯形按钮两梯形的斜边&#xff0c;对接再一起&#xff0c;组成一个矩形斜边附近的区域能点击 【原型图】 【方案】 canvas——斜边附近的区域无法点击Shape——斜边附近的区域无法点击clipShape——完美解决 【代码】 Entry Component struct …

Spring Task 使用详解

在应用开发中&#xff0c;定时任务扮演着至关重要的角色&#xff0c;例如定时数据同步、定时邮件发送、定时清理缓存等。Spring Framework 提供了一个强大而灵活的定时任务框架——Spring Task&#xff0c;它可以帮助我们轻松地实现各种定时任务&#xff0c;而无需依赖复杂的第…

光影魔术手 0.1.5 | 免费的修图神器,支持AI智能美颜、证件照制作等功能

光影魔术手是一款完全免费的修图软件、AI智能调色软件、证件照制作软件。支持的功能包括&#xff1a;AI智能美颜、AI人脸变清晰、AI智能调色、AI滤镜、拼图、证件照制作、图片裁剪。证件照制作功能提供了丰富的证件照尺寸&#xff0c;支持7种背景颜色切换。拼图功能支持横向长图…

XXl-JOB 安装使用,服务注册

一、下载源码 xxl-job源码地址&#xff1a; GitHub - xuxueli/xxl-job: A distributed task scheduling framework.&#xff08;分布式任务调度平台XXL-JOB&#xff09; 2.4.2版本为例&#xff1a;https://github.com/xuxueli/xxl-job/archive/refs/tags/2.4.1.tar.gz xx…

2013年国赛高教杯数学建模C题古塔的变形解题全过程文档及程序

2013年国赛高教杯数学建模 C题 古塔的变形 由于长时间承受自重、气温、风力等各种作用&#xff0c;偶然还要受地震、飓风的影响&#xff0c;古塔会产生各种变形&#xff0c;诸如倾斜、弯曲、扭曲等。为保护古塔&#xff0c;文物部门需适时对古塔进行观测&#xff0c;了解各种变…

【交通标志识别系统】Python+卷积神经网络算法+人工智能+深度学习+机器学习+算法模型

一、介绍 交通标志识别系统。本系统使用Python作为主要编程语言&#xff0c;在交通标志图像识别功能实现中&#xff0c;基于TensorFlow搭建卷积神经网络算法模型&#xff0c;通过对收集到的58种常见的交通标志图像作为数据集&#xff0c;进行迭代训练最后得到一个识别精度较高…

C语言中的文件操作(一)

目录 一、为什么要使用文件 二、什么是文件 1、程序文件 2、数据文件 文件名 三、文件打开和关闭 1、文件指针 2、文件打开关闭 &#xff08;1&#xff09;fopen 打开 &#xff08;2&#xff09;fclose 关闭文件 &#xff08;3&#xff09;路径 1.绝对路径 2.相对路…

子网掩码、网络地址、广播地址、子网划分及计算

1. IPV4地址分类及组成 IP地址网络地址主机地址&#xff0c;&#xff08;又称&#xff1a;主机号和网络号&#xff09; 由上图可见网络号和主机号之和是32&#xff0c;而且此多彼少。 例&#xff1a;IP地址为192.168.2.131&#xff0c;转换成二进制1111 1111.1010 1000.0000 00…

编译原理——扫描器设计与实现

非常详细&#xff08;包括跳过注释部分&#xff09;&#xff0c;不多说直接上代码&#xff08;结合代码讲解&#xff09; #include<bits/stdc.h>using namespace std;#define ARRAY_LENGTH(arr) (sizeof(arr) / sizeof(arr[0]))//关键词集合 string KEY_WORD[] {"…

vue+ant解决弹窗可以拖动的问题

通过自定义指令实现拖拽功能 在main.js里加入drag自定义指令 Vue.directive(drag, {bind(el) {// 获取弹窗头部const header el.querySelector(.ant-modal-header)const modal el.querySelector(.ant-modal)// 弹窗头部鼠标变为移动header.style.cursor move// 头部鼠标按…

心觉:别再让你的精力流浪,精准掌控每一刻

Hi&#xff0c;我是心觉&#xff0c;与你一起玩转潜意识、脑波音乐和吸引力法则&#xff0c;轻松掌控自己的人生&#xff01; 挑战每日一省写作197/1000天 昨天写了一篇文章心觉&#xff1a;生理欲望转化的奥秘&#xff1a;提升创造力的法则 核心观点是来自于拿破仑希尔的《…

ICML 2024 | 牛津提出合作图神经网络Co-GNNs,更灵活的消息传递新范式

引用次数:9 引用格式:Finkelshtein B, Huang X, Bronstein M, et al. Cooperative graph neural networks[J]. arXiv preprint arXiv:2310.01267, 2023. 一、摘要 本文提出了一种训练图神经网络的新框架“合作图神经网络”(Co-GNNs),其中每一个节点可以被看作一个独立的玩…

【数据结构】邻接表

一、概念 邻接表是一个顺序存储与链式存储相结合的数据结构&#xff0c;用于描述一个图中所有节点之间的关系。 若是一个稠密图&#xff0c;我们可以选择使用邻接矩阵&#xff1b;但当图较稀疏时&#xff0c;邻接矩阵就显得比较浪费空间了&#xff0c;此时我们就可以换成邻接…

grpc的python使用

RPC 什么是 RPC &#xff1f; RPC&#xff08;Remote Procedure Call&#xff09;远程过程调用&#xff0c;是一种计算机通信协议&#xff0c;允许一个程序&#xff08;客户端&#xff09;通过网络向另一个程序&#xff08;服务器&#xff09;请求服务&#xff0c;而无需了解…

JDK17常用新特性

目前国内大部分开发人员都是在使用jdk8&#xff0c;甚至是jdk6&#xff0c;但是随着jdk的更新迭代&#xff0c;jdk8我觉得可能就会慢慢的淡出舞台&#xff0c;随着目前主流框架最新版推出明确说明了不再支持jdk8&#xff0c;也促使我不得不抓紧学习了解一波jdk17的新特性&#…

手写mybatis之解析和使用ResultMap映射参数配置

前言 学习源码是在学习什么呢&#xff1f; 就是为了通过这些源码级复杂模型中&#xff0c;学习系统框架的架构思维、设计原则和设计模式。在这些源码学习手写的过程中&#xff0c;感受、吸收并也是锻炼一种思维习惯&#xff0c;并尝试把这些思路技术迁移到平常的复杂业务设计开…