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中指定了以下字符为保留字符:! * ’ ( ) ; : @ & = + $ , / ? # [ ])。
解决方案选择:
- 前端请求时encode特殊字段(算了,不能因为自己的原因加大前端工作量)
- 改用post请求(emmm没有办法的办法,看着难受就是想要改了)
- 改Tomcat配置文件(由于是springboot项目,内嵌了tomcat,不方便修改,好吧就是我比较菜)
- 在后端代码层面解决这个问题
解决方法:
其他服务:由于使用的是内嵌的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基本操作
功能: 命令行模式下的文本编辑器。根据文件扩展名自动判别编程语言。支持代码缩进、代码高亮等功能。使用方式:vim filename 如果已有该文件,则打开它。 如果没有该文件,则打开个一个新的文件,并命名为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()算子,适用于一些无法用单一灰度进行分割的情况,如背景比较复杂,有的部分比前景目标亮,或者有的部分比前景目标暗;又比如前景目标包…...
jvm介绍
1. JVM是什么 JVM是Java Virtual Machine的缩写,即咱们经常提到的Java虚拟机。虚拟机是一种抽象化的计算机,有着自己完善的硬件架构,如处理器、堆栈等,具体有什么咱们不做了解。目前我们只需要知道想要运行Java文件,必…...
数据结构与算法课后题-第三章(顺序队和链队)
#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 查询订单,以及订单关联的用户的信息! 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: sh nfs_install.sh /mnt/data03 10.60.41.0/24nfs_install.sh #!/bin/bash### How to i…...
7.3 调用函数
前言: 思维导图: 7.3.1 函数调用的形式 我的笔记: 函数调用的形式 在C语言中,调用函数是一种常见的操作,主要有以下几种调用方式: 1. 函数调用语句 此时,函数调用独立存在,作为…...
如果使用pprof来进行性能的观测和优化
1. 分析性能瓶颈 在开始优化之前,首先需要确定你的程序的性能瓶颈在哪里。使用性能分析工具(例如 Go 的内置 pprof 包)来检测程序中消耗时间和内存的地方。这可以帮助你确定需要优化的具体部分。 2. 选择适当的数据结构和算法 选择正确的数…...
在移动固态硬盘上安装Ubuntu系统和ROS2
目录 原视频准备烧录 原视频 b站鱼香ros 准备 1.在某宝上买一个usb移动固态硬盘或固态U盘,至少64G 2.下载鱼香ros烧录工具 下载第二个就行了,不然某网盘的速度下载全部要一天 下载后,选择FishROS2OS制作工具压缩包,进行解压…...
【iptables 实战】02 iptables常用命令
一、iptables中基本的命令参数 -P 设置默认策略-F 清空规则链-L 查看规则链-A 在规则链的末尾加入新规则-I num 在规则链的头部加入新规则-D num 删除某一条规则-s 匹配来源地址IP/MASK,加叹号“!”表示除这个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级样题 闰年统计 题目描述 小明刚刚学习了如何判断平年和闰年,他想知道两个年份之间(包含起始年份和终止年份)有几个闰年。你能帮帮他吗? 输入格式 输入一行,包含两个整数,分别表示起始年份和终止…...
CentOS密码重置
背景: 我有一个CentOS虚拟机,但是密码忘记了,偶尔记起可以重置密码,于是今天尝试记录一下,又因为我最近记性比较差,所以必须要记录一下。 过程: 1、在引导菜单界面(grubÿ…...
Tomcat Servlet
Tomcat & Servlet 一、What is “Tomcat”?二、 What is “Servlet”?1、HttpServlet2、HttpServletRequest3、HttpServletResponse 一、What is “Tomcat”? Tomcat 本质上是一个基于 TCP 协议的 HTTP 服务器。我们知道HTTP是一种应用层协议,是 HTTP 客户端…...
国庆day2---select实现服务器并发
select.c: #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 的发展如火如荼,在可观测性领域大放异彩,Grafana 近期也发布了一款 eBPF 采集器,可以采集服务的 RED 指标,本文做一个尝鲜介绍,让读者有个大概了解。 eBPF 基础介绍可以参考我之前的文章《eBPF Hello world》。理…...
亲测可用国产GPT人工智能
分享一些靠谱、可用、可以白嫖的GPT大模型。配合大模型,工作效率都会极大提升。 清华大学ChatGLM 官网: 智谱清言中国版对话语言模型,与GLM大模型进行对话。https://chatglm.cn/开源的、支持中英双语的1300亿参数的对话语言模型࿰…...
适配器模式详解和实现(设计模式 四)
适配器模式将一个类的接口转换成客户端所期望的另一个接口,解决由于接口不兼容而无法进行合作的问题。 设计基本步骤 1. 创建目标接口(Target Interface),该接口定义了客户端所期望的方法。 2.创建被适配类(Adaptee…...
IDEA的使用
文章目录 1.IDEA配置1.1 idea界面说明1.2 git1.3 JDK1.4 maven1.5 Tomcat1.6 idea设置编码格式1.7 vscodenodejs1.8 windows下安装redis 2. IDEA问题2.1 setAttribute方法爆红2.2 idea cannot download sources解决办法2.3 springboot项目跑起来不停run 3. vscode3.1 vscode显示…...
CSS详细基础(二)文本样式
插播一条CSS的工作原理: CSS是一种定义样式结构如字体、颜色、位置等的语言,被用于描述网页上的信息格式化和显示的方式。CSS样式可以直接存储于HTML网页或者单独的样式单文件。无论哪一种方式,样式单包含将样式应用到指定类型的元素的规则。…...
win10系统任务栏图标变成白色的解决办法
我平时都是用滴答清单进行管理这个自己的日程代办的,但是今天打开的时候发现这个快捷方式突然变成纯白色的了,重启电脑之后,这个图标的样式仍然没有变化。上网查找解决办法之后,终于搞好了,于是就有了下面的教程。 为什…...
hadoop生态现状、介绍、部署
一、引出hadoop 1、hadoop的高薪现状 各招聘平台都有许多hadoop高薪职位,可以看看职位所需求的技能 ----> hadoop是什么,为什么会这么高薪?引出大数据,大数据时代,大数据与云计算 2、大数据时代的介绍 大数据的故事…...
二、EFCore 数据库表的创建和迁移
文章目录 一、数据库连接二、数据库表迁移一、数据库连接 在NuGet上安装EntityFramework 代码如下: Microsoft.EntityFrameworkCoreMicrosoft.EntityFrameworkCore.SqlServerMicrosoft.Extensions.Configuration.Json配置数据连接 appsettings.json 增加数据库连接配置 &quo…...
在nodejs中使用typescript
在nodejs中使用typescript 如果我们正在使用nodejs来开发应用,那么对于管理和扩展一个大型代码库来说是一个非常大的挑战。克服这一问题的方法之一是使用typescript,为js添加可选的类型注释和高级功能。在本文中,我们将探讨如何使用在nodejs中使用types…...
数据结构与算法基础(青岛大学-王卓)(8)
哎呀呀,sorry艾瑞波地,这次真的断更一个月了,又发生了很多很多事情,秋风开始瑟瑟了,老父亲身体查出肿瘤了,有病请及时就医,愿每一个人都有一个健康的身体,God bless U and FAMILY. 直…...
【生物信息学】使用谱聚类(Spectral Clustering)算法进行聚类分析
目录 一、实验介绍 二、实验环境 1. 配置虚拟环境 2. 库版本介绍 3. IDE 三、实验内容 0. 导入必要的工具 1. 生成测试数据 2. 绘制初始数据分布图 3. 循环尝试不同的参数组合并计算聚类效果 4. 输出最佳参数组合 5. 绘制最佳聚类结果图 6. 代码整合 一、实验介绍…...
CSS基础语法第二天
目录 一、复合选择器 1.1 后代选择器 1.2 子代选择器 1.3 并集选择器 1.4 交集选择器 1.4.1超链接伪类 二、CSS特性 2.1 继承性 2.2 层叠性 2.3 优先级 基础选择器 复合选择器-叠加 三、Emmet 写法 3.1HTML标签 3.2CSS 四、背景属性 4.1 背景图 4.2 平铺方式 …...
ThreeJS - 封装一个GLB模型展示组件(TypeScript)
一、引言 最近基于Three.JS,使用class封装了一个GLB模型展示,支持TypeScript、支持不同框架使用,具有多种功能。 (下图展示一些基础的功能,可以自行扩展,比如光源等) 二、主要代码 本模块依赖…...
网站后台管理系统栏目位置/怎么推广自己的网站
发送端和接收端的TCP会话维护了32位的序列号( sequence number ),用来记录发送了多少数据,而 TCP报文确认序号(acknowledgement number) 表示了有多少数据成功接收了。通常初始的序列号是随机的,可能的范围在 0 到4,294,967,295。wireshark中默认采用了相对序号,为了便于分…...
wordpress邮件内容/百度地图疫情实时动态
使用JPA查询数据,对查询出来的结果进行修改,但是不保存数据库,最终数据库却做了同样的修改。 // 托管状态 User user this.findById(id); //当使用set方法这一部时已经同步保存到数据库了 user.setName("李四"); //此时这里就会报…...
提交网站/近期热点新闻事件
利用java打开一张图片,并提取其边缘。功能有打开文件,以及提取边缘。算法原理由于边缘提取的算法有很多种,而提取的精度在相同阈值的情况下也会有不同的结果。这次我的边缘提取使用索贝尔算子(Sobel operator)。该算子会把图像每一点的灰度矢…...
烟台市住房和规划建设管理局网站/网上推广专员是什么意思
转载于:https://www.cnblogs.com/cicser/archive/2010/07/20/1781437.html...
dw做的网站怎样做成手机版的/女教师遭网课入侵视频大全
CSS部分: 一、CSS优先级: !important > 行内样式 > ID选择器 > 类选择器 > 标签 > 通配符 > 继承 > 浏览器默 认属性同一级别。 二、盒子模型: IE盒子模型:width border padding 内容宽度 W3C标准盒子模型…...
wordpress扫描附件到新浪图床/建站合肥网络公司seo
1 如何将字串 String 转换成整数 int?A. 有两个方法:1). int i Integer.parseInt([String]); 或i Integer.parseInt([String],[int radix]);2). int i Integer.valueOf(my_str).intValue();注: 字串转成 Double, Float, Long 的方法大同小异.2 如何将整数 int 转换成字串 S…...