众所周知,springCloud gateway用的是异步请求方式,即webflux。

当拦截请求时,如url包含大括号“{}”特殊字符时,会报Failed to get request URI: xxx 异常。

此时需要正确请求访问,需要重写源码中相应方法:

package org.springframework.http.server.reactive;import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.cookie.Cookie;
import io.netty.handler.ssl.SslHandler;
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Iterator;
import java.util.Set;
import javax.net.ssl.SSLSession;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.NettyDataBufferFactory;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpHeaders;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import reactor.core.publisher.Flux;
import reactor.ipc.netty.ByteBufFlux;
import reactor.ipc.netty.http.server.HttpServerRequest;/*** 重写initUri(HttpServerRequest request)方法,处理请求参数中{}被网关拦截的问题*/
class ReactorServerHttpRequest extends AbstractServerHttpRequest {private final HttpServerRequest request;private final NettyDataBufferFactory bufferFactory;public ReactorServerHttpRequest(HttpServerRequest request, NettyDataBufferFactory bufferFactory) throws URISyntaxException {super(initUri(request), "", initHeaders(request));Assert.notNull(bufferFactory, "DataBufferFactory must not be null");this.request = request;this.bufferFactory = bufferFactory;}private static URI initUri(HttpServerRequest request) throws URISyntaxException {Assert.notNull(request, "HttpServerRequest must not be null");return new URI(resolveBaseUrl(request).toString() + resolveRequestUri(request));}private static URI resolveBaseUrl(HttpServerRequest request) throws URISyntaxException {String scheme = getScheme(request);String header = request.requestHeaders().get(HttpHeaderNames.HOST);if (header != null) {int portIndex;if (header.startsWith("[")) {portIndex = header.indexOf(58, header.indexOf(93));} else {portIndex = header.indexOf(58);}if (portIndex != -1) {try {return new URI(scheme, (String)null, header.substring(0, portIndex), Integer.parseInt(header.substring(portIndex + 1)), (String)null, (String)null, (String)null);} catch (NumberFormatException var5) {throw new URISyntaxException(header, "Unable to parse port", portIndex);}} else {return new URI(scheme, header, (String)null, (String)null);}} else {InetSocketAddress localAddress = (InetSocketAddress)request.context().channel().localAddress();return new URI(scheme, (String)null, localAddress.getHostString(), localAddress.getPort(), (String)null, (String)null, (String)null);}}private static String getScheme(HttpServerRequest request) {ChannelPipeline pipeline = request.context().channel().pipeline();boolean ssl = pipeline.get(SslHandler.class) != null;return ssl ? "https" : "http";}private static String resolveRequestUri(HttpServerRequest request) {String uri = request.uri();for(int i = 0; i < uri.length(); ++i) {char c = uri.charAt(i);if (c == '/' || c == '?' || c == '#') {break;}if (c == ':' && i + 2 < uri.length() && uri.charAt(i + 1) == '/' && uri.charAt(i + 2) == '/') {for(int j = i + 3; j < uri.length(); ++j) {c = uri.charAt(j);if (c == '/' || c == '?' || c == '#') {return uri.substring(j);}}return "";}}return uri;}private static HttpHeaders initHeaders(HttpServerRequest channel) {HttpHeaders headers = new HttpHeaders();Iterator var2 = channel.requestHeaders().names().iterator();while(var2.hasNext()) {String name = (String)var2.next();headers.put(name, channel.requestHeaders().getAll(name));}return headers;}public String getMethodValue() {return this.request.method().name();}protected MultiValueMap<String, HttpCookie> initCookies() {MultiValueMap<String, HttpCookie> cookies = new LinkedMultiValueMap();Iterator var2 = this.request.cookies().keySet().iterator();while(var2.hasNext()) {CharSequence name = (CharSequence)var2.next();Iterator var4 = ((Set)this.request.cookies().get(name)).iterator();while(var4.hasNext()) {Cookie cookie = (Cookie)var4.next();HttpCookie httpCookie = new HttpCookie(name.toString(), cookie.value());cookies.add(name.toString(), httpCookie);}}return cookies;}public InetSocketAddress getRemoteAddress() {return this.request.remoteAddress();}@Nullableprotected SslInfo initSslInfo() {SslHandler sslHandler = (SslHandler)this.request.context().channel().pipeline().get(SslHandler.class);if (sslHandler != null) {SSLSession session = sslHandler.engine().getSession();return new DefaultSslInfo(session);} else {return null;}}public Flux<DataBuffer> getBody() {ByteBufFlux var10000 = this.request.receive().retain();NettyDataBufferFactory var10001 = this.bufferFactory;var10001.getClass();return var10000.map(var10001::wrap);}public <T> T getNativeRequest() {return (T) this.request;}
}

通过修改该类中的initUri方法实现“{}”特殊字符通过网关,不被拦截。

具体替换为:

private static URI initUri(HttpServerRequest request) throws URISyntaxException {Assert.notNull(request, "HttpServerRequest must not be null");// 针对 特殊字符 { } 做替换处理String requestUri = resolveRequestUri(request).replace("{", "%7B").replace("}", "%7D");return new URI(resolveBaseUrl(request).toString() + requestUri);}

经测试,能正常访问。

ps:目前springBoot版本为:2.X。

基于springCloud gateway请求包含url包含{}大括号特殊字符的问题相关推荐

  1. SpringCloud Gateway——请求转发源码分析

    SpringCloud Gateway--请求转发源码分析 1. 分享目的 SpringCloud Gateway功能很多,其中使用了非阻塞的WebFlux框架让人印象深刻,想学习这种WebFlux的 ...

  2. 一次因reactor-netty bug导致springcloud gateway请求积压问题处理

    项目中再使用springcloud gateway做微服务网关,在线上的环境忽然发现有时候接口会出现卡顿,更多集中在登陆的时候,而且卡顿呈现不确定性再检查springcloud gateway的日志时 ...

  3. springcloud gateway 请求执行流程分析

    一.示例 pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http:// ...

  4. 【SpringCloud】请求响应报错cannot be cast to org.springframework.core.io.buffer.NettyDataBufferFactory

    springcloud gateway请求响应报错 org.springframework.core.io.buffer.DefaultDataBufferFactory cannot be cast ...

  5. iOS开发网络篇 一一 请求路径(URL)中文转码问题

    当发送网络请求: 确定请求路径URL 时, 观察url中是否包含中文, 如果包含中文 需要将url中的中文进行转码操作. 注意: 上面这种情况 只针对于发送GET请求,因为GET请求的URL 包含用户 ...

  6. pandas基于dataframe字符串数据列不包含特定字符串来筛选dataframe中的数据行(rows where values do not contain substring)

    pandas基于dataframe字符串数据列不包含(not contains)特定字符串来筛选dataframe中的数据行(rows where values do not contain subs ...

  7. 基于Spark的新闻推荐系统,包含爬虫项目、web网站以及spark推荐系统

    下载地址:https://download.csdn.net/download/ouyangxiaobai123/22174377 项目介绍: 基于Spark的新闻推荐系统,包含爬虫项目.web网站以 ...

  8. PHP远程文件包含(RFI)并绕过远程URL包含限制

    文章来源|MS08067 公众号粉丝投稿 本文作者:VastSky(Ms08067实验室粉丝) 前言 本文我们讲如何绕过远程URL包含限制.在PHP开发环境php.ini配置文里"allow ...

  9. php 怎么远程包含,利用PHP应用程序中的远程文件包含(RFI)并绕过远程URL包含限制...

    前言 文章讲诉了如何绕过远程URL包含限制.在PHP开发环境php.ini配置文件里",allow_url_include"为"off"的情况下,不允许PHP加 ...

  10. android 基于豆瓣 Api 的客户端,包含电影分类,图书分类,电影榜单,收藏功能,搜索功能。

    JianDou 项目地址:ChinaLHR/JianDou 简介:基于豆瓣 Api 的客户端,包含电影分类,图书分类,电影榜单,收藏功能,搜索功能. 更多:作者   提 Bug   示例 APK    ...

最新文章

  1. Android 自定义圆形图片 CircleImageView
  2. svn 回归某一个特定版本
  3. linux中的for命令
  4. python 为什么没有重载_python是否支持重载
  5. 笔记3——C++类的一些特性
  6. sharepoint column中的图片链接不能显示为图片
  7. python中的json注意事项
  8. 零基础学Python【二十三、图形化界面设计 】(基础一篇全,欢迎认领)
  9. Hyperledger中数据存取的实现
  10. 解决/mnt中有hgfs无共享文件
  11. day05 数据类型
  12. 【Python实例第25讲】稳健的 vs 经验的协方差估计
  13. 如何在ogre游戏界面添加自己的信息,比如显示某变量的值
  14. paip.JAVA的几大优点与缺点相比C#.NET.txt
  15. 印象笔记支持Markdown语法
  16. vs2010学习版安装与激活
  17. C#之DES加密解密
  18. C++ —— (两个经纬度计算距离、方位角)、(经纬度A+距离+方位,计算目标经纬度)、(多个经纬度计算面积)
  19. 网易我的世界服务器加载无响应,我的世界网易版开始游戏没反应
  20. python speed为0但是速度过快_python代码加速

热门文章

  1. numpy的array()函数
  2. Unity 预编译选项
  3. 入职美团定级P7,最新最全180道高级岗面试题及答案
  4. 网吧服务器组装方案,网吧服务器配置方案有哪些
  5. 计算机的内存时序参数,电脑内存条很重要的一个参数:时序
  6. Canceled future for execute_request message before replies were done The Kernel crashed while execut
  7. wincc提示项目管理器服务器不可用,Wincc新建文件时提示项目管理器 服务器不可用...
  8. 安装Ubuntu系统时硬盘分区最合理的方法
  9. java工具类_16 个超级实用的 Java 工具类
  10. python按顺序执行函数_Python3的unittest用例按编写顺序执行