SpringCloudGateway网关整合swagger3+Knife4j3,basePath丢失请求404问题

news2024/11/28 6:40:30

在集成 Spring Cloud Gateway 网关的时候,会出现没有 basePath 的情况,例如定义的 /jeeplus-auth、/jeeplus-system 等微服务前缀导致访问接口404:

maven依赖:

swagger2于17年停止维护,现在最新的版本为 Swagger3(Open Api3)

<knife4j.version>3.0.3</knife4j.version>

在这里插入图片描述

直接访问是找不到url的:

在这里插入图片描述

如果手动添加前缀是可以的

在这里插入图片描述
在这里插入图片描述
但是每一个接口都要手动添加前缀太繁琐了,也失去了用swagger接口的意义;这时候我们需要在 Gateway 网关添加一个 Filter 过滤器:

在网关模块添加一个过滤器SwaggerGlobalFilter:

在这里插入图片描述

过滤器代码:

package com.jeeplus.gateway.filter;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.reactivestreams.Publisher;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

/**
 * swagger v3/api-docs缺失basePath 过滤器
 *
 * @Author 955
 * @Date 2022-09-22 11:31
 * @Description
 */
@Slf4j
@Component
public class SwaggerGlobalFilter  implements GlobalFilter, Ordered{
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String path = request.getPath().toString();
        String host = request.getLocalAddress().getHostString();
        int port = request.getLocalAddress().getPort();
        if (!path.endsWith("/v3/api-docs")) {
            return chain.filter(exchange);
        }
        String[] pathArray = path.split("/");
        System.out.println(pathArray);
        String basePath = pathArray[1];
        ServerHttpResponse originalResponse = exchange.getResponse();
        // 定义新的消息头
        ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
            @Override
            public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
                if (super.getStatusCode().equals(HttpStatus.OK) && body instanceof Flux) {
                    Flux<? extends DataBuffer> fluxBody = Flux.from(body);
                    return super.writeWith(fluxBody.buffer().map(dataBuffers -> {
                        List<String> list = new ArrayList<>();
                        dataBuffers.forEach(dataBuffer -> {
                            byte[] content = new byte[dataBuffer.readableByteCount()];
                            dataBuffer.read(content);
                            DataBufferUtils.release(dataBuffer);
                            list.add(new String(content, Charset.forName("UTF-8")));
                        });
                        String s = this.listToString(list);
                        JSONObject jsonObject = JSON.parseObject(s);

                        jsonObject.put("host", host + ":" + port);
                        jsonObject.put("basePath", basePath);
                        s = jsonObject.toString();
                        // 设置更新后的header请求头长度
                        int length = s.getBytes().length;
                        HttpHeaders headers = originalResponse.getHeaders();
                        headers.setContentLength(length);
                        return bufferFactory().wrap(s.getBytes(Charset.forName("UTF-8")));
                    }));
                }
                return super.writeWith(body);
            }

            @Override
            public HttpHeaders getHeaders() {
                // 获取父类原始ServerHttpResponse的header请求头信息,这是代理Delegate类型
                HttpHeaders httpHeaders = super.getHeaders();
                httpHeaders.set(HttpHeaders.CONTENT_TYPE, "application/json;charset=UTF-8");
                return httpHeaders;
            }

            private String listToString(List<String> list) {
                StringBuilder stringBuilder = new StringBuilder();
                for (String s : list) {
                    stringBuilder.append(s);
                }
                return stringBuilder.toString();
            }
        };

        // replace response with decorator
        return chain.filter(exchange.mutate().response(decoratedResponse).build());
    }

    @Override
    public int getOrder() {
        return -2;
    }

}

重启再次查看发现已经正常了。

在这里插入图片描述

测试一下接口:

在这里插入图片描述

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

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

相关文章

光引擎、光模块、光器件之间的关系和区别

最近小编有收到一些用户问“光引擎、光模块、光器件之间的关系和区别&#xff1f;”&#xff0c;众所周知光通信技术一直在不断演进&#xff0c;为满足不断增长的数据传输需求提供了强大的解决方案。而光通信系统中&#xff0c;光引擎、光模块和光器件是关键的组成部分&#xf…

2023-10-07 LeetCode每日一题(股票价格跨度)

2023-10-07每日一题 一、题目编号 901. 股票价格跨度二、题目链接 点击跳转到题目位置 三、题目描述 设计一个算法收集某些股票的每日报价&#xff0c;并返回该股票当日价格的 跨度 。 当日股票价格的 跨度 被定义为股票价格小于或等于今天价格的最大连续日数&#xff08…

Openfire身份认证绕过漏洞

漏洞详情&#xff1a; Openfire是采用Java编程语言开发的实时协作服务器&#xff0c;Openfire的管理控制台是一个基于Web的应用程序&#xff0c;被发现可以使用路径遍历的方式绕过权限校验。未经身份验证的用户可以访问Openfire管理控制台中的后台页面。同时由于Openfire管理控…

情侣飞行棋情侣游戏源码

之前的链接失效了&#xff0c;所以重新补充一个 最近很火的抖音上非常火的东西 首先是源码下载地址&#xff1a; http://pan.xiaou61.top/down.php/892e381f7cdb508b5ac55fc9fc0047b3.zip 然后是演示地址&#xff1a; http://fxq.xiaou61.top/#/ 2023最新情侣飞行棋源码 最新情…

bigemap在林业勘测规划设计行业的一些应用

选择Bigemap的原因&#xff1a; 主要注重影像的时效性&#xff0c;软件的影像时效性比其他的更新快&#xff0c;更清晰。 使用场景&#xff1a; 1.林业督查&#xff0c;主要是根据国家下发的图斑&#xff0c;结合测绘局的影像以及bigemap的较新影像对比去年和今年的林地变化。…

php生成海报和指定文字

public function createPoster($parmas){$content mb_convert_encoding(这是一张海报, "html-entities", "utf-8");$config array(text>array(array(text>$content,left>500,top>100,fontPath>C:\Users\ahuyikao\Desktop\Alibaba-PuHuiTi…

Python算法练习 10.8

leetcode 2352 相等行列对 给你一个下标从 0 开始、大小为 n x n 的整数矩阵 grid &#xff0c;返回满足 Ri 行和 Cj 列相等的行列对 (Ri, Cj) 的数目。 如果行和列以相同的顺序包含相同的元素&#xff08;即相等的数组&#xff09;&#xff0c;则认为二者是相等的。 输入&am…

C语言:常量

目录 C语言中的常量分为以下以下几种&#xff1a; 字面常量 const修饰的常变量 #define定义的标识符常量 枚举常量 C语言中的常量分为以下以下几种&#xff1a; 字面常量const修饰的常变量#define定义的标识符常量枚举常量 字面常量 const修饰的常变量 在c语言中&#xff…

【本地方法接口和本地方法栈】

文章目录 简单地讲&#xff0c; 一个 Native Method 是一个 Java 调用非 Java 代码的接囗。一个 Native Method 是这样一个 Java 方法&#xff1a;该方法的实现由非 Java 语言实现&#xff0c;比如 C。 Java 虚拟机栈于管理 Java 方法的调用&#xff0c;而本地方法栈用于管理本…

【MySQL】就这一篇帮你解决 MySQL 磁盘占用过高的问题

这篇博客主要是来解决 mysql 落盘日志占用磁盘空间过大的问题。我是用 docker 启动的 mysql&#xff0c;然后把 /var/lib/mysql 挂载到宿主机上。有人反馈网页点击无反应&#xff0c;我想的是这么简单&#xff0c;也没改动怎么会报错呢。上服务器&#xff0c;刚好无意看了下 df…

【力扣521】最长特殊序列 Ⅰ

&#x1f451;专栏内容&#xff1a;力扣刷题⛪个人主页&#xff1a;子夜的星的主页&#x1f495;座右铭&#xff1a;前路未远&#xff0c;步履不停 目录 一、题目描述二、题目分析 一、题目描述 题目链接&#xff1a;最长特殊序列 Ⅰ 给你两个字符串 a 和 b&#xff0c;请返回…

[LMKD] [Android] 进程OomAdj调整分析:OomAdj状态简要(1)

一. 什么是OomAdj oomAdj是Android系统中的一个进程内存管理参数&#xff0c;它决定了系统在内存不足时回收进程的顺序。oomAdj的值越小&#xff0c;说明该进程越重要&#xff0c;越不容易被系统回收。Android系统会根据进程的oomAdj值来决定哪些进程应该被回收&#xff0c;以…

arm-三盏灯流水

.text .global _start _start: 1.设置GPIOE寄存器的时钟使能 RCC_MP_AHB4ENSETR[4]->1 0x50000a28 LDR R0,0x50000A28 LDR R1,[R0] ORR R1,R1,#(0x3<<4) 第四位第五位都设置为1 STR R1,[R0] 写回2.设置PE10管脚为输出模式 GPIOE_MODER[21:20]->01 0x5000…

【数据结构】迷宫问题DFS非递归(c语言实现)

本来之前写过一个推箱子&#xff0c;就想着写个迷宫游戏&#xff0c;因为想着推箱子游戏里面也有墙&#xff0c;也有玩家的移动&#xff0c;比推箱子简单的是还不用判断前面是否有箱子的情况&#xff0c;但是自己写的迷宫游戏如果自己随机生成的迷宫地图的话&#xff0c;不一定…

Altium Designer培训 | 3 - PCB库创建篇

参考文章 http://t.csdnimg.cn/T6ykf PCB封装的元素 PCB焊盘&#xff0c;焊接器件用的。管脚序号&#xff0c;和原理图管脚一一对应。丝印&#xff0c;是实物本体的大小范围。1脚标识&#xff0c;定位器件的正反方向。阻焊&#xff0c;防绿油覆盖的&#xff0c;把铜露出来&…

使用Windows系统自带的安全加密解密文件操作步骤详解

原以为安全加密的方法是加密压缩包&#xff0c;有的需要用软件加密文件&#xff0c;可每次想往里面修改或存放文件都要先解密&#xff0c;不用时&#xff0c;还得去加密&#xff0c;操作步骤那么多&#xff0c;那多不方便呀&#xff0c;这里讲讲用系统自带的BitLocker加密工具怎…

基于SSM的固定资产管理系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

Linux命令基本用法

1.用户相关命令 1.账号管理 命令作用useradd添加用户passwd设置密码usermod修改用户userdel删除用户su切换用户 例&#xff1a; [rootlocalhost ~]# useradd aaa [rootlocalhost ~]# su aaa [aaalocalhost root]$ su root 密码&#xff1a; [rootlocalhost ~]# passwd aaa …

DynamicIPAccess.java

package webspider_20230929_paypal;import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL;/*** 动态IP访问** author ZengWenFeng* date 2023.10.08* email 117791303qq.com* mobile 13805029595*/ pub…

CDN,DNS,ADN,SCDN,DCDN,ECDN,PCDN,融合CDN的介绍

一、CDN是什么&#xff1f; CDN的全称是Content Delivery Network&#xff0c;即内容分发网络。其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节&#xff0c;使内容传输得更快、更稳定。通过在网络各处放置节点服务器所构成的在现有的互联网基础之…