当前位置: 首页 > news >正文

SpringCloud + SpringGateway 解决Get请求传参为特殊字符导致400无法通过网关转发的问题


title: “SpringCloud + SpringGateway 解决Get请求传参为特殊字符导致400无法通过网关转发的问题”
createTime: 2021-11-24T10:27:57+08:00
updateTime: 2021-11-24T10:27:57+08:00
draft: false
author: “Atomicyo”
tags: [“tomcat”]
categories: [“java”]
description: “SpringCloud + SpringGateway 解决Get请求传参为特殊字符导致400无法通过网关转发的问题”


SpringCloud + SpringGateway 解决Get请求传参为特殊字符导致400无法通过网关转发的问题

场景:

公司以前的框架统一使用Post请求,传入参数为一个定义的公共类,类里面有个String类型的bean字段传入json字符串作为传参,emmm就想给他改成restful风格,在传入参数公共类无法改变的情况下,Get请求会传入特殊字符,导致400错误。例如:

localhost:10001/verify/compreport/month?data={"compRefOwid":"1448487922485252098", "yhMonth":"2021-10"}

原因:

Tomcat的新版本中增加了一个新特性,就是严格按照 RFC 3986规范进行访问解析,而 RFC 3986规范定义了Url中只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~4个特殊字符以及所有保留字符(RFC3986中指定了以下字符为保留字符:! * ’ ( ) ; : @ & = + $ , / ? # [ ])。

解决方案选择:

  1. 前端请求时encode特殊字段(算了,不能因为自己的原因加大前端工作量)
  2. 改用post请求(emmm没有办法的办法,看着难受就是想要改了)
  3. 改Tomcat配置文件(由于是springboot项目,内嵌了tomcat,不方便修改,好吧就是我比较菜)
  4. 在后端代码层面解决这个问题

解决方法:

其他服务:由于使用的是内嵌的tomcat,网上常见的
解决spring boot请求包含非法字符问题 The valid characters are defined in RFC 7230 and RFC 3986 错误
配置TomcatServletWebServerFactory的方式使用时会导致两个TomcatServletWebServerFactory使springboot项目报错Unable to start ServletWebServerApplicationContext due to multiple ServletWebServerFactory beans而无法启动。而使用yml配置的方式也无法生效。

server:tomcat:relaxed-query-chars:- "<"- ">"- "["- "]"- "{"- "}"

随后参考了继承WebServerFactoryCustomizer的方式来修改Tomcat配置

SpringBoot2.0.0新版本内嵌Tomcat配置

import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;/*** Tomcat配置* @author Atomicyo* @version 1.0
createTime: 2021-11-24T10:27:57+08:00
updateTime: 2021-11-24T10:27:57+08:00*/
@Component
public class MyTomcatWebServerCustomize implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {private int maxParameterCount = 10000;@Overridepublic void customize(TomcatServletWebServerFactory factory) {PropertyMapper propertyMapper = PropertyMapper.get();propertyMapper.from(this::getMaxParameterCount).when(v -> true).to(v -> customizerProperty(factory));}/*** params特殊字符过滤* @param factory* @return void* @author Atomicyo
createTime: 2021-11-24T10:27:57+08:00
updateTime: 2021-11-24T10:27:57+08:00* @version 1.0*/private void customizerProperty(TomcatServletWebServerFactory factory) {factory.addConnectorCustomizers(connector -> connector.setProperty("relaxedQueryChars", "[]{}"));}public void setMaxParameterCount(int maxParameterCount) {this.maxParameterCount = maxParameterCount;}public int getMaxParameterCount() {return maxParameterCount;}
}

网关模块:

由于spring gateway使用的是netty作为服务。所以修改tomcat配置的方式无法生效。参考Spring Cloud Gateway 和 Webflux 请求参数非法字符处理

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.HttpRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;
import reactor.netty.ConnectionObserver;
import reactor.netty.NettyPipeline;import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;/*** Netty编码配置* @author Atomicyo* @version 1.0
createTime: 2021-11-24T10:27:57+08:00
updateTime: 2021-11-24T10:27:57+08:00*/
@Component
@Slf4j
public class EncodeQueryNettyWebServerCustomizer implements WebServerFactoryCustomizer<NettyReactiveWebServerFactory> {/*** 需要encode的特殊字符*/private final List<Character> charList = new ArrayList<Character>() {{this.add('{');this.add('}');this.add('[');this.add(']');}};@Overridepublic void customize(NettyReactiveWebServerFactory factory) {factory.addServerCustomizers(httpServer ->httpServer.observe((conn, state) -> {if (state == ConnectionObserver.State.CONNECTED) {conn.channel().pipeline().addAfter(NettyPipeline.HttpCodec, "",  new QueryHandler());}}));}class QueryHandler extends ChannelInboundHandlerAdapter {public QueryHandler() {}@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws UnsupportedEncodingException {if (msg instanceof HttpRequest) {HttpRequest request = (HttpRequest) msg;String url = request.uri();// fix urllog.info("url: {}", url);String[] split = url.split("\\?");StringBuilder fixUrl = new StringBuilder(split[0]);if (split.length > 1) {fixUrl.append("?");char[] chars = split[1].toCharArray();for (char aChar : chars) {if (charList.contains(aChar)) {fixUrl.append(URLEncoder.encode(String.valueOf(aChar), "UTF-8"));}else {fixUrl.append(aChar);}}}log.info("fixUrl: {}", fixUrl);request.setUri(fixUrl.toString());}ctx.fireChannelRead(msg);}}
}

验证:

在这里插入图片描述

相关文章:

SpringCloud + SpringGateway 解决Get请求传参为特殊字符导致400无法通过网关转发的问题

title: “SpringCloud SpringGateway 解决Get请求传参为特殊字符导致400无法通过网关转发的问题” createTime: 2021-11-24T10:27:5708:00 updateTime: 2021-11-24T10:27:5708:00 draft: false author: “Atomicyo” tags: [“tomcat”] categories: [“java”] description: …...

vim基本操作

功能&#xff1a; 命令行模式下的文本编辑器。根据文件扩展名自动判别编程语言。支持代码缩进、代码高亮等功能。使用方式&#xff1a;vim filename 如果已有该文件&#xff0c;则打开它。 如果没有该文件&#xff0c;则打开个一个新的文件&#xff0c;并命名为filename 模式…...

Drift plus penalty 漂移加惩罚Part1——介绍和工作原理

文章目录 正文Methodology 方法论Origins and applications 起源和应用How it works 它是怎样工作的The stochastic optimization problem 随机优化问题Virtual queues 虚拟队列The drift-plus-penalty expression 漂移加惩罚表达式Drift-plus-penalty algorithmApproximate sc…...

(四)动态阈值分割

文章目录 一、基本概念二、实例解析 一、基本概念 基于局部阈值分割的dyn_threshold()算子&#xff0c;适用于一些无法用单一灰度进行分割的情况&#xff0c;如背景比较复杂&#xff0c;有的部分比前景目标亮&#xff0c;或者有的部分比前景目标暗&#xff1b;又比如前景目标包…...

jvm介绍

1. JVM是什么 JVM是Java Virtual Machine的缩写&#xff0c;即咱们经常提到的Java虚拟机。虚拟机是一种抽象化的计算机&#xff0c;有着自己完善的硬件架构&#xff0c;如处理器、堆栈等&#xff0c;具体有什么咱们不做了解。目前我们只需要知道想要运行Java文件&#xff0c;必…...

数据结构与算法课后题-第三章(顺序队和链队)

#include <iostream> //引入头文件 using namespace std;typedef int Elemtype;#define Maxsize 5 #define ERROR 0 #define OK 1typedef struct {Elemtype data[Maxsize];int front, rear;int tag; }SqQueue;void InitQueue(SqQueue& Q) //初始化队列 {Q.rear …...

SSM - Springboot - MyBatis-Plus 全栈体系(十六)

第三章 MyBatis 三、MyBatis 多表映射 2. 对一映射 2.1 需求说明 根据 ID 查询订单&#xff0c;以及订单关联的用户的信息&#xff01; 2.2 OrderMapper 接口 public interface OrderMapper {Order selectOrderWithCustomer(Integer orderId); }2.3 OrderMapper.xml 配置…...

k8s--storageClass自动创建PV

文章目录 一、storageClass自动创建PV1.1 安装NFS1.2 创建nfs storageClass1.3 测试自动创建pv 一、storageClass自动创建PV 这里使用NFS实现 1.1 安装NFS 安装nfs-server&#xff1a; sh nfs_install.sh /mnt/data03 10.60.41.0/24nfs_install.sh #!/bin/bash### How to i…...

7.3 调用函数

前言&#xff1a; 思维导图&#xff1a; 7.3.1 函数调用的形式 我的笔记&#xff1a; 函数调用的形式 在C语言中&#xff0c;调用函数是一种常见的操作&#xff0c;主要有以下几种调用方式&#xff1a; 1. 函数调用语句 此时&#xff0c;函数调用独立存在&#xff0c;作为…...

如果使用pprof来进行性能的观测和优化

1. 分析性能瓶颈 在开始优化之前&#xff0c;首先需要确定你的程序的性能瓶颈在哪里。使用性能分析工具&#xff08;例如 Go 的内置 pprof 包&#xff09;来检测程序中消耗时间和内存的地方。这可以帮助你确定需要优化的具体部分。 2. 选择适当的数据结构和算法 选择正确的数…...

在移动固态硬盘上安装Ubuntu系统和ROS2

目录 原视频准备烧录 原视频 b站鱼香ros 准备 1.在某宝上买一个usb移动固态硬盘或固态U盘&#xff0c;至少64G 2.下载鱼香ros烧录工具 下载第二个就行了&#xff0c;不然某网盘的速度下载全部要一天 下载后&#xff0c;选择FishROS2OS制作工具压缩包&#xff0c;进行解压…...

【iptables 实战】02 iptables常用命令

一、iptables中基本的命令参数 -P 设置默认策略-F 清空规则链-L 查看规则链-A 在规则链的末尾加入新规则-I num 在规则链的头部加入新规则-D num 删除某一条规则-s 匹配来源地址IP/MASK&#xff0c;加叹号“&#xff01;”表示除这个IP外-d 匹配目标地址-i 网卡名称 匹配从这块…...

webview_flutter

查看webview内核 ​https://liulanmi.com/labs/core.html​ h5中获取设备 https://cloud.tencent.com/developer/ask/sof/105938013 https://developer.mozilla.org/zh-CN/docs/Web/API/Navigator/mediaDevices web资源部署后navigator获取不到mediaDevices实例的解决方案&…...

【GESP考级C++】1级样题 闰年统计

GSEP 1级样题 闰年统计 题目描述 小明刚刚学习了如何判断平年和闰年&#xff0c;他想知道两个年份之间&#xff08;包含起始年份和终止年份&#xff09;有几个闰年。你能帮帮他吗&#xff1f; 输入格式 输入一行&#xff0c;包含两个整数&#xff0c;分别表示起始年份和终止…...

CentOS密码重置

背景&#xff1a; 我有一个CentOS虚拟机&#xff0c;但是密码忘记了&#xff0c;偶尔记起可以重置密码&#xff0c;于是今天尝试记录一下&#xff0c;又因为我最近记性比较差&#xff0c;所以必须要记录一下。 过程&#xff1a; 1、在引导菜单界面&#xff08;grub&#xff…...

Tomcat Servlet

Tomcat & Servlet 一、What is “Tomcat”?二、 What is “Servlet”?1、HttpServlet2、HttpServletRequest3、HttpServletResponse 一、What is “Tomcat”? Tomcat 本质上是一个基于 TCP 协议的 HTTP 服务器。我们知道HTTP是一种应用层协议&#xff0c;是 HTTP 客户端…...

国庆day2---select实现服务器并发

select.c&#xff1a; #include <myhead.h>#define ERR_MSG(msg) do{\fprintf(stderr,"__%d__:",__LINE__);\perror(msg);\ }while(0)#define IP "192.168.1.3" #define PORT 8888int main(int argc, const char *argv[]) {//创建报式套接字socketi…...

Grafana 开源了一款 eBPF 采集器 Beyla

eBPF 的发展如火如荼&#xff0c;在可观测性领域大放异彩&#xff0c;Grafana 近期也发布了一款 eBPF 采集器&#xff0c;可以采集服务的 RED 指标&#xff0c;本文做一个尝鲜介绍&#xff0c;让读者有个大概了解。 eBPF 基础介绍可以参考我之前的文章《eBPF Hello world》。理…...

亲测可用国产GPT人工智能

分享一些靠谱、可用、可以白嫖的GPT大模型。配合大模型&#xff0c;工作效率都会极大提升。 清华大学ChatGLM 官网&#xff1a; 智谱清言中国版对话语言模型&#xff0c;与GLM大模型进行对话。https://chatglm.cn/开源的、支持中英双语的1300亿参数的对话语言模型&#xff0…...

适配器模式详解和实现(设计模式 四)

适配器模式将一个类的接口转换成客户端所期望的另一个接口&#xff0c;解决由于接口不兼容而无法进行合作的问题。 设计基本步骤 1. 创建目标接口&#xff08;Target Interface&#xff09;&#xff0c;该接口定义了客户端所期望的方法。 2.创建被适配类&#xff08;Adaptee…...

3KW无线充电系统设计:开环控制与闭环控制的MATLAB Simulink仿真模型,采用双边L...

3KW无线充电系统设计&#xff08;MATLAB simulink仿真模型&#xff09; 控制方式&#xff1a;开环控制闭环控制 拓扑结构&#xff1a;双边LCC拓扑结构 输入电压&#xff1a;750V 输出电压&#xff1a;400V 传输功率&#xff1a;3KW 最近在折腾一个3KW无线充电系统的仿真项目&am…...

Vivado仿真踩坑实录:PR模式不支持仿真的快速解决方案(附详细步骤)

Vivado仿真避坑指南&#xff1a;PR模式不支持仿真的深度解析与实战方案 刚接触FPGA开发的朋友们&#xff0c;不知道你们是否遇到过这样的场景&#xff1a;在Vivado中精心设计了一个工程&#xff0c;准备进行仿真验证时&#xff0c;突然弹出一个令人困惑的错误提示——"Sim…...

Charticulator:数据可视化的自由创作平台与技术革命

Charticulator&#xff1a;数据可视化的自由创作平台与技术革命 【免费下载链接】charticulator Interactive Layout-Aware Construction of Bespoke Charts 项目地址: https://gitcode.com/gh_mirrors/ch/charticulator 当数据分析师面对预设模板无法表达复杂数据关系时…...

给黑帮写反侦测系统:他们在暗网给我立生祠

作为一名软件测试工程师&#xff0c;我从未想过&#xff0c;我的专业技能会让我卷入一场数字世界的道德深渊。故事始于一个匿名加密邮件&#xff0c;主题简洁却充满诱惑&#xff1a;“高薪项目&#xff1a;反侦测系统开发。”客户承诺丰厚报酬&#xff0c;并强调需要顶尖测试思…...

YOLOv8工业缺陷检测推理延迟骤降63%:基于TensorRT量化+ONNX Runtime定制化内核的完整链路

第一章&#xff1a;YOLOv8工业缺陷检测推理延迟骤降63%&#xff1a;基于TensorRT量化ONNX Runtime定制化内核的完整链路在高吞吐产线场景下&#xff0c;YOLOv8原生PyTorch模型在Jetson AGX Orin上单帧推理延迟达84.2ms&#xff08;输入尺寸640640&#xff09;&#xff0c;严重制…...

Qwen3-ASR-1.7B新手必看:常见问题解决,音频格式、长音频处理技巧

Qwen3-ASR-1.7B新手必看&#xff1a;常见问题解决&#xff0c;音频格式、长音频处理技巧 1. 引言&#xff1a;语音识别模型的基础认知 语音识别技术正在改变我们处理音频数据的方式。Qwen3-ASR-1.7B作为一款多语言语音识别模型&#xff0c;为开发者提供了强大的离线转写能力。…...

aircrack-ng使用教程

aircrack-ng是一款用于无线网络安全评估的工具套件&#xff0c;主要用于破解WEP和WPA/WPA2-PSK加密的无线网络密码。它通过分析捕获的数据包&#xff0c;利用密码破解技术来获取网络密钥&#xff0c;是网络安全测试和渗透测试中常用的工具之一。该工具支持多种攻击模式和优化选…...

GitHub Desktop汉化终极指南:如何让英文界面瞬间变成中文

GitHub Desktop汉化终极指南&#xff1a;如何让英文界面瞬间变成中文 【免费下载链接】GitHubDesktop2Chinese GithubDesktop语言本地化(汉化)工具 项目地址: https://gitcode.com/gh_mirrors/gi/GitHubDesktop2Chinese 还在为GitHub Desktop的英文界面而头疼吗&#xf…...

告别DWA!用TEB局部规划器让你的ROS机器人学会‘倒车入库’(附多机编队避障实测对比)

告别DWA&#xff01;用TEB局部规划器解锁机器人高阶机动能力 在机器人自主导航领域&#xff0c;传统动态窗口方法(DWA)长期占据主导地位&#xff0c;直到开发者们遇到那些需要倒车、急转弯或狭窄空间多机协作的真实场景。想象一下仓储机器人需要在货架间完成"倒车入库&quo…...

Keepalived+Nginx+Tomcat 高可用项目集成 MySQL 数据库全记录

前言在之前的文章中&#xff0c;我搭建了基于 KeepalivedNginxTomcat 的高可用 Web 架构&#xff0c;实现了入口 VIP 漂移和反向代理。但这套架构还缺少“数据层”——所有服务都是无状态的&#xff0c;不能持久化数据。为了让项目更完整&#xff0c;我决定加入 MySQL 数据库&a…...