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

Tomcat get请求传数组集合参数

前言

最近做项目,需要通过GET传参,来实现查询的能力,本来是RPC调用,直接参数序列化即可。但是服务最近修改为HTTP,本来Spring Cloud的feign也可以直接传参数,但是当使用Nginx访问时参数到底传啥呢,笔者传入?list=['xxx']直接就报错了,错误类型

Invalid character found in the request target [/haha?list=[%27haha%27] ]. The valid characters are defined in RFC 7230 and RFC 3986

准备demo

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.7.18</version></dependency>

demo随意写,写个springboot项目,实际上跟servlet容器有关,Boot默认Tomcat,其他servlet容器可能实现标准不一样而不同。

    @GetMapping("/haha")public String sayHello(List<String> list){return list.toString();}

如果我们自己实现http get,实际上就是针对url的参数解析,说不定?list=['xxx']就不会报错,追根溯源--标准的实现区别。

日志如下

源码分析

查询资料:RFC 7230: Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routingicon-default.png?t=N7T8https://www.rfc-editor.org/rfc/rfc7230

    这个标准定义了400状态码http 1.1协议的一些规则

RFC 3986: Uniform Resource Identifier (URI): Generic Syntax icon-default.png?t=N7T8https://www.rfc-editor.org/rfc/rfc3986     定义了保留字符

   

很不幸[]属于保留字符。

从Tomcat的源码看org.apache.coyote.http11.Http11InputBuffer的parseRequestLine方法。

} else if (parsingRequestLineQPos != -1 && !httpParser.isQueryRelaxed(chr)) {// Avoid unknown protocol triggering an additional errorrequest.protocol().setString(Constants.HTTP_11);// %nn decoding will be checked at the point of decodingString invalidRequestTarget = parseInvalid(parsingRequestLineStart, byteBuffer);throw new IllegalArgumentException(sm.getString("iib.invalidRequestTarget", invalidRequestTarget));
}

逐个字符读取。发现是保留字符则根据标准抛出异常,提示根据什么标准。

 在org.apache.tomcat.util.http.parser.HttpParser的静态代码块中,定义了通常不允许的字符。

static {for (int i = 0; i < ARRAY_SIZE; i++) {// Control> 0-31, 127if (i < 32 || i == 127) {IS_CONTROL[i] = true;}// Separatorif (i == '(' || i == ')' || i == '<' || i == '>' || i == '@' || i == ',' || i == ';' || i == ':' ||i == '\\' || i == '\"' || i == '/' || i == '[' || i == ']' || i == '?' || i == '=' || i == '{' ||i == '}' || i == ' ' || i == '\t') {IS_SEPARATOR[i] = true;}// Token: Anything 0-127 that is not a control and not a separatorif (!IS_CONTROL[i] && !IS_SEPARATOR[i] && i < 128) {IS_TOKEN[i] = true;}// Hex: 0-9, a-f, A-Fif ((i >= '0' && i <= '9') || (i >= 'a' && i <= 'f') || (i >= 'A' && i <= 'F')) {IS_HEX[i] = true;}// Not valid for HTTP protocol// "HTTP/" DIGIT "." DIGITif (i == 'H' || i == 'T' || i == 'P' || i == '/' || i == '.' || (i >= '0' && i <= '9')) {IS_HTTP_PROTOCOL[i] = true;}if (i >= '0' && i <= '9') {IS_NUMERIC[i] = true;}if (i >= 'a' && i <= 'z' || i >= 'A' && i <= 'Z') {IS_ALPHA[i] = true;}if (IS_ALPHA[i] || IS_NUMERIC[i] || i == '+' || i == '-' || i == '.') {IS_SCHEME[i] = true;}if (IS_ALPHA[i] || IS_NUMERIC[i] || i == '-' || i == '.' || i == '_' || i == '~') {IS_UNRESERVED[i] = true;}if (i == '!' || i == '$' || i == '&' || i == '\'' || i == '(' || i == ')' || i == '*' || i == '+' ||i == ',' || i == ';' || i == '=') {IS_SUBDELIM[i] = true;}// userinfo = *( unreserved / pct-encoded / sub-delims / ":" )if (IS_UNRESERVED[i] || i == '%' || IS_SUBDELIM[i] || i == ':') {IS_USERINFO[i] = true;}// The characters that are normally not permitted for which the// restrictions may be relaxed when used in the path and/or query// string// 明确定义通常不允许使用的字符,当然也可以放开限制,当为路径或者查询参数if (i == '\"' || i == '<' || i == '>' || i == '[' || i == '\\' || i == ']' || i == '^' || i == '`' ||i == '{' || i == '|' || i == '}') {IS_RELAXABLE[i] = true;}}DEFAULT = new HttpParser(null, null);}

至此我们知道了数组和集合使用get传参报错的原因:明确定义通常不允许使用的字符,当然也可以放开限制,当为路径或者查询参数。 

解决办法

解决办法也简单了,解析参数规避'[' ']'这样的字符即可,比如string默认tolist,使用string,string传list或者数组对象等,解析规则实际上我们甚至可以自定义,参考Tomcat或者springboot的规则。

比如使用字符串:实际上springboot就是这么做的,tomcat毕竟GET仅传递String字段,各种参数类型都是后面Springboot转换的

 如果使用List直接注入,那么因为没有构造函数,报错,毕竟接口类型,反射无法初始化对象。

因为Springboot会反射解析对象,所以即使使用ArrayList也不能解析参数,因为默认情况仅能解析String

 只有@RequestParam绑定参数key才行

因为解析器不一样,具体就不分析了,涉及Springmvc的设计。

 

数组或者集合使用,分割。

 

实际上还有其他办法:我们可以放开限制,只需要注入HttpParser即可

在tomcat协议定义里面org.apache.coyote.http11.AbstractHttp11Protocol

定义了

那么我们只要注入这2个值即可,第一个是路径字符,第2个是查询字符,根据最小修改原则,此处注入查询参数。根据Springboot自动装配org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration的属性注入即可

 application.properties文件

server.tomcat.relaxedQueryChars=<,>,[,\,],^,`,{,|,}

即可实现放开限制

 

但是tomcat认为'[' ']'是字符串的字符,以,逗号分割。

 

并不符合我们的直观感受,所以还是一个原则,只不过是允许'[' ']'这样的字符了。  

总结

通过tomcat GET传参数,尤其是数组或者集合,发现tomcat实现了很多开源标准,预估其他servlet容器也差不多,如果是我们自己实现servlet容器解析http协议包,那么这些标准估计是不会去实现的,开源的能力定义了一系列标准并且基本上都实现了。而Springboot在tomcat标准的基础上转换了各种类型,实现了方便快速的开发。

相关文章:

Tomcat get请求传数组集合参数

前言 最近做项目&#xff0c;需要通过GET传参&#xff0c;来实现查询的能力&#xff0c;本来是RPC调用&#xff0c;直接参数序列化即可。但是服务最近修改为HTTP&#xff0c;本来Spring Cloud的feign也可以直接传参数&#xff0c;但是当使用Nginx访问时参数到底传啥呢&#xf…...

信息学奥赛初赛天天练-34-CSP-J2021完善程序-按位异或、模拟算法、数组模拟环、约瑟夫问题应用

PDF文档公众号回复关键字:20240624 2021 CSP-J 完善程序3 1 完善程序 (单选题 &#xff0c;每小题3分&#xff0c;共30分) &#xff08;Josephus问题&#xff09;有n个人围成一个圈&#xff0c;依次标号0至n-1。从0号开始&#xff0c;依次 0&#xff0c;1&#xff0c;0&#…...

【计算机视觉】人脸算法之图像处理基础知识(六)

图像直方图 图像直方图是描述图像中像素强度分布的一种统计图表&#xff0c;它是图像处理和计算机视觉领域中一个非常基础且重要的概念。图像直方图通常用于分析图像的亮度、对比度特性&#xff0c;以及在图像增强、阈值分割、特征提取等多种图像处理任务。 import cv2 impor…...

仓颉编程语言入门

华为在 2024 年 6 月 21 日的华为开发者大会上&#xff0c;华为终端 BG 软件部总裁龚体正式官宣了华为自研仓颉编程语言&#xff0c;并发布了 HarmonyOS NEXT 仓颉语言开发者预览版。 仓颉编程语言文件后缀名为 .cj, 以下是第一个入门代码输出&#xff1a;你好&#xff0c;仓颉…...

在前端项目中,如何处理错误和异常?

在前端项目中&#xff0c;如何处理错误和异常&#xff1f; 在前端项目中&#xff0c;处理错误和异常是至关重要的&#xff0c;它能确保应用程序的稳定性和用户体验。以下是一些常见的方法&#xff1a; try-catch-finally结构&#xff1a;使用JavaScript的try/catch块来捕获并…...

Ubuntu系统下修改网卡IP地址

Ubuntu系统下修改网卡IP地址 一、Ubuntu系统介绍1.1 Ubuntu简介1.2 Ubuntu网络配置方式 二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍 三、检查本地环境3.1 检查本地操作系统版本3.2 检查系统内核版本 四、配置网卡IP地址4.1 备份网卡配置文件4.2 查看当前IP地址4.3 修改…...

Scrapy如何对爬虫数据进行清洗和处理?

爬虫数据处理是数据采集应用中至关重要的一步。scrapy是一种流行的python爬虫框架&#xff0c;可以帮助我们快速高效地从网页中提取所需信息。但是&#xff0c;我们经常面临的一个问题是数据的质量低劣&#xff0c;存在各种噪声和错误&#xff0c;这使得它们难以用于后续分析和…...

Linux:基础IO(三.软硬链接、动态库和静态库、动精态库的制作和加载)

上次介绍了基础IO&#xff08;二&#xff09;&#xff1a;Linux&#xff1a;基础IO&#xff08;二.缓冲区、模拟一下缓冲区、详细讲解文件系统&#xff09; 文章目录 1.软硬链接1.1硬链接1.2软链接使用场景 2.动态库和静态库1.1回顾1.2静态库的制作和使用为什么要有库制作者角度…...

低价可转债崩盘,发生了什么?

下跌不在于“出库”&#xff0c;甚至不在于“风险”。问题更多在于交易层面&#xff0c;何时能积聚更多的左侧资金并成功过渡至右侧。 低价券怎么了&#xff1f; 如果说6月初主要是小微盘品种的退市风险&#xff0c;后来是一些评级下调的品种&#xff0c;到本周&#xff0c;已…...

【面试题】马上金九银十了,简历该准备起来了,面试题你准备好了吗 ?浅谈 JS 浅拷贝和深拷贝

代码展示 let obj_old {name: Tom,age: 15,favorite: {food: bread,drink: milk} } let obj_new {...obj_old} console.log(obj_old obj_new) // false console.log(obj_old.name obj_new.name) // true console.log(obj_old.favorite obj_new.favorite) // true3. Ar…...

最新OPPO 真我手机 一加手机 使用adb命令永久关闭系统更新教程

使用adb命令永久关闭系统更新 一、先了解手机系统二、Android 11 以下使用adb 命令永久关闭系统更新1、adb 官方下载2、小白开启 USB 调试模式教程&#xff08;熟手跳过&#xff09;三、Android 12 以上使用adb 命令永久关闭系统更新什么您还是不会弄&#xff01;赞赏我&#x…...

OnlyOffice:现代办公的最佳选择

目录 安装 使用 评价 对比&#xff08;与WPS&#xff09; 总结 在当今的数字化办公时代&#xff0c;选择一款功能全面且易于使用的办公软件至关重要。OnlyOffice作为一款现代化的办公软件&#xff0c;凭借其强大的功能和友好的用户体验&#xff0c;逐渐成为了众多企业和个…...

【收藏】2024年必备相图数据库资源集锦!

在材料化工领域&#xff0c;相图不仅仅是一个简单的图表&#xff0c;它是一个强大的工具&#xff0c;为材料科学家和工程师提供了深入理解材料行为的窗口。从选择合金元素及其比例的初步阶段&#xff0c;到后续的加工方法选择和热处理工艺的确定&#xff0c;相图都扮演着至关重…...

Zookeeper 二、Zookeeper环境搭建

Zookeeper安装方式有三种&#xff0c;单机模式和集群模式以及伪集群模式 单机模式&#xff1a;Zookeeper只运行在一台服务器上&#xff0c;适合测试环境集群模式&#xff1a;Zookeeper运行于一个集群上&#xff0c;适合生产环境&#xff0c;这个计算机集群被称为一个“集合体”…...

Web3 学习

之前学习 web3&#xff0c;走了不少弯路&#xff0c;最近看到了 hackquest&#xff0c;重新刷了一遍以太坊基础&#xff0c;感觉非常nice&#xff0c;而且完全免费&#xff0c;有需要的可以试试&#xff0c;链接hackquest.io。...

Grafana+Prometheus(InfluxDB)+Jmeter使用Nginx代理搭建可视化性能测试监控平台

前言 在这篇博客文章中&#xff0c;将分享JMeter > Prometheus(InfluxDB) > Grafana的集成&#xff0c;以及Nginx端口反向代理各服务的端口。 背景 在JMeter插件库中&#xff0c;有一些后端监听器可供Kafka、ElasticSearch和Azure使用。默认情况下&#xff0c;JMeter支…...

web学习笔记(六十六)项目总结

目录 1. Suspense标签 2.发布订阅者模式 3.pinia的使用 4.在请求过来的数据添数据 5.设置token和取token 6. 实现触底加载 7.导航守卫判断登录状态。 1. Suspense标签 Suspense主要用于用于处理异步组件加载和数据获取。&#xff0c;使用这个标签可以允许你在组件等待数…...

红队内网攻防渗透:内网渗透之内网对抗:横向移动篇域控系统提权NetLogonADCSPACKDC永恒之蓝CVE漏洞

红队内网攻防渗透 1. 内网横向移动1.1 横向移动-域控提权-CVE-2020-1472 NetLogon1.2 横向移动-域控提权-CVE-2021-422871.3 横向移动-域控提权-CVE-2022-269231.4 横向移动-系统漏洞-CVE-2017-01461.5 横向移动-域控提权-CVE-2014-63241. 内网横向移动 1、横向移动-域控提权-…...

VMware Workstation安装Windows Server2019系统详细操作步骤

虚拟机版本 VMware Workstation 16 Prp 16.2.5 build-20904516 实现操作 创建虚拟机 创建新的虚拟机 自定义->下一步 默认即可&#xff0c;下一步 稍后安装操作系统->下一步 按照图下所示选择好系统->下一步 设置好虚拟机名称和位置->下一步 默认即可&#xff0…...

HTML5【新特性总结】

HTML5【新特性总结】 HTML5 的新增特性主要是针对于以前的不足&#xff0c;增加了一些新的标签、新的表单和新的表单属性等。 这些新特性都有兼容性问题&#xff0c;基本是 IE9 以上版本的浏览器才支持&#xff0c;如果不考虑兼容性问题&#xff0c;可以大量使用这些新特性。…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词

Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵&#xff0c;其中每行&#xff0c;每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid&#xff0c;其中有多少个 3 3 的 “幻方” 子矩阵&am…...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下&#xff0c;限制某个 IP 的访问频率是非常重要的&#xff0c;可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案&#xff0c;使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

NPOI Excel用OLE对象的形式插入文件附件以及插入图片

static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...

Spring Security 认证流程——补充

一、认证流程概述 Spring Security 的认证流程基于 过滤器链&#xff08;Filter Chain&#xff09;&#xff0c;核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤&#xff1a; 用户提交登录请求拦…...

uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)

UniApp 集成腾讯云 IM 富媒体消息全攻略&#xff08;地理位置/文件&#xff09; 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型&#xff0c;核心实现方式&#xff1a; 标准消息类型&#xff1a;直接使用 SDK 内置类型&#xff08;文件、图片等&#xff09;自…...

PH热榜 | 2025-06-08

1. Thiings 标语&#xff1a;一套超过1900个免费AI生成的3D图标集合 介绍&#xff1a;Thiings是一个不断扩展的免费AI生成3D图标库&#xff0c;目前已有超过1900个图标。你可以按照主题浏览&#xff0c;生成自己的图标&#xff0c;或者下载整个图标集。所有图标都可以在个人或…...

STM32标准库-ADC数模转换器

文章目录 一、ADC1.1简介1. 2逐次逼近型ADC1.3ADC框图1.4ADC基本结构1.4.1 信号 “上车点”&#xff1a;输入模块&#xff08;GPIO、温度、V_REFINT&#xff09;1.4.2 信号 “调度站”&#xff1a;多路开关1.4.3 信号 “加工厂”&#xff1a;ADC 转换器&#xff08;规则组 注入…...