异常:Invalid character found in the request target. The valid characters are defined in RFC 3986
一、背景
事情是这样的,前几天做一个基本的数据库“增删改查”的需求,前端传参的方式是“JSON字符串”,后端接收到此参数后,使用阿里巴巴fastjson进行解析,然后入库。需求很简单吧,但是偏偏遇到问题了。
我发现,JSON字符串里面无数组,纯粹的都是json结构的时候,即都是“{}”时,不会报错,传参入库没问题。但是只要传参的值里面有数组,即有“[]”的结构时,就报错。报错内容如下(我的tomcat版本是8.5.45):
java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
at org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:479)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:684)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:800)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1471)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
二、原因
tomcat的原因。 tomcat严格按照RFC规范进行范文解析,随着网络环境的变化,RFC规范也在不断的修改和升级中,发布了好多版本。而tomcat的不同版本中,采用的RFC规范的版本是不同的。所以你会在下文发现,有的低版本tomcat没有这个问题。
tomcat自tomcat 8.0.35版本之后对URL参数做了比较规范的限制,必须遵循RFC 7230 and RFC 3986规范,对于非保留字字符(json格式的请求参数)必须做转义操作。例如:RFC 3986规范定义了Url中只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~4个特殊字符以及所有保留字符(RFC3986中指定了以下字符为保留字符:! * ’ ( ) ; : @ & = + $ , / ? # [ ])。
Request For Comments(RFC),是一系列以编号排定的文件。文件收集了有关互联网相关信息,以及UNIX和互联网社区的软件文件。目前RFC文件是由Internet Society(ISOC)赞助发行。基本的互联网通信协议都有在RFC文件内详细说明。RFC文件还额外加入许多在标准内的论题,例如对于互联网新开发的协议及发展中所有的记录。因此几乎所有的互联网标准都有收录在RFC文件之中——百度百科。
附上网络大牛的源码分析:
分析的是org.apache.tomcat.util.http.parser.HttpParser //tomcat 8.2.3 版本及 tomcat 7.0.82 ,都有如下代码,读取配置
String prop = System.getProperty("tomcat.util.http.parser.HttpParser.requestTargetAllow");
if (prop != null) {
for (int i = 0; i < prop.length(); i++) {
char c = prop.charAt(i);
if (c == '{' || c == '}' || c == '|') {
REQUEST_TARGET_ALLOW[c] = true;
} else {
log.warn(sm.getString("httpparser.invalidRequestTargetCharacter",Character.valueOf(c)));
}
}
} 而tomcat 8.0.14 版本中并没有读取配置,对 | { } 的处理,而是默认为合法字符。
static {
for (int i = 0; i < 128; i++) {
if (i < 32) {
isToken[i] = false;
} else if (i == '(' || i == ')' || i == '<' || i == '>' || i == '@' ||
i == ',' || i == ';' || i == ':' || i == '\\' || i == '\"' ||
i == '/' || i == '[' || i == ']' || i == '?' || i == '=' ||
i == '{' || i == '}' || i == ' ' || i == '\t') {
isToken[i] = false;
} else {
isToken[i] = true;
}
if (i >= '0' && i <= '9' || i >= 'A' && i <= 'F' ||i >= 'a' && i <= 'f') {
isHex[i] = true;
} else {
isHex[i] = false;
}
}
}
可以看出在 8.0.x 左右的一些版本中,tomcat.util.http.parser.HttpParser. requestTargetAllow (下文方法三)这个配置是没有生效的,即| { } 这3个符号认为是合法的。
三、解决
注:我是使用“方法五”解决问题的,推荐“方法五”。
方法一:换到低版本的Tomcat。
方法二:在Catalina.properties中添加tomcat.util.http.parser.HttpParser.requestTargetAllow=|{}这个东西明显是允许“|”和大括号的,但是我现在的问题是中括号。
方法三:添加tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true这个是允许url中带有特殊字符的。试过了,也不好使。
方法四:对传递的“JSON字符串”进行url编码后在传递,可以规避这个方括号。前端用“encodeURI(xxx)”方法编码,后端用“URLDecoder.decode(xxx, "utf-8")”解码即可。
方法五:在tomcat目录的conf文件夹下,server.xml的Connector中添加了这个relaxedQueryChars="[,]"。
注:
1、如果还有其他特殊的字符串,也可以直接添加到这个属性里;
2、如果你是springboot项目,可以在SpringBootApplication的的main方法中增加:System.setProperty("tomcat.util.http.parser.HttpParser.requestTargetAllow","[]"); 
参考
1、https://blog.csdn.net/Hitler698/article/details/85720156
2、https://my.oschina.net/pding/blog/1794176
异常:Invalid character found in the request target. The valid characters are defined in RFC 3986的更多相关文章
- Tomcat 8 Invalid character found in the request target. The valid characters are defined in RFC 3986
终极解决方案: Invalid character found in the request target. The valid characters are defined in RFC 3986 ...
- tomcat Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
1.情景展示 tomcat 日志时不时会报出如下异常信息,到底是怎么回事? java.lang.IllegalArgumentException: Invalid character found ...
- Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC
解决Invalid character found in the request target. The valid characters are defined in RFC 7230 and RF ...
- Tomcat v7.0 java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
十二月 , :: 下午 org.apache.coyote.http11.AbstractHttp11Processor process 信息: Error parsing HTTP request ...
- 解决springboot项目请求出现非法字符问题 java.lang.IllegalArgumentException:Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
springboot版本: 2.1.5 最近使用springboot搭建了一个App后台服务的项目,开发接口的时候在本机使用postman工具做请求测试,请求返回一直很正常,但是在前端开发使用h5请求 ...
- Tomcat报错Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
问题描述:后台报错 Note: further occurrences of HTTP header parsing errors will be logged at DEBUG level.java ...
- 已解决:Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986 问题
请求: http://127.0.0.1:8080/driverApp/findLikeAddress?json={"shopname":"广东省"," ...
- IE浏览器连接WebSocket报错:java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
在项目开发中整合了WebSocket,本来没什么问题了,但是偶尔发现用IE浏览器打开web端不能推送消息,因为PC端与服务器建立连接失败了.网上查了很多资料, 又看了看源码,都不对症:又怀疑是Spri ...
- IE浏览器报400错误:Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
前言: 在用IE浏览器时访问tomcat项目时,页面报400错误,后台错误: java.lang.IllegalArgumentException: Invalid character found i ...
随机推荐
- sqlplus 导出一张表数据
内网只让用sql developer 这软件搓的不行,数据加载到51行就黑了,没法法用sqlplus. 打开cmd, sqlplus user/passwd@ip:port/库名set colsep ...
- Vue —— 从环境搭建到发布
之前学习 Vue 的时候也是按着别人的文档一步步下载安装构建项目再运行,为了避免忘记步骤,所以还是记在这吧. 参考链接: https://www.zybuluo.com/xudongh/note/75 ...
- Gokit微服务-服务链路追踪
https://mp.weixin.qq.com/s/gjKOy4SDpsjUXDC3Q1YdFw Gokit微服务-服务链路追踪 原创: 兮一昂吧 兮一昂吧 2月28日
- 多位IT专家分享他们离不开的实用工具
本文的 PDF版本可供下载. #1: John Bartow,顾问 John Bartow的工作领域是网络和PC安全,他提供了自己从事的咨询公司, WinHaven Computer Consulti ...
- openpose关节图
- LODOP纸张高度不定的纯文本累计高度
小票由于纸张没有确定的高度,根据内容多少,小票打印机出多少纸,在设置纸张的时候,需要把纸张设置成不定高的纸张.简短问答:小票打印 ,参考样例18 http://www.c-lodop.com/demo ...
- 【leetcode】521. Longest Uncommon Subsequence I
problem 521. Longest Uncommon Subsequence I 最长非共同子序列之一 题意: 两个字符串的情况很少,如果两个字符串相等,那么一定没有非共同子序列,反之,如果两个 ...
- Ubuntu 14.04安装Python3
1.添加源 sudo add-apt-repository ppa:fkrull/deadsnakes 2.更新 & 安装 sudo apt-get update sudo apt- pyth ...
- 第一章 python+selenium自动化测试实战
@序章 自动化测试是软件测试的主流方向之一: 教程从测试的根本需求出发,讲解如何开展自动化测试. 首先,我们要明白,自动化仅仅是满足我们某种需求的一种工具:没有必要花费时间把它全部弄懂:我们只需要学会 ...
- ssh自动添加hostkey到know_hosts
The authenticity of host ‘git.sws.com (10.42.1.88)’ can’t be established. ECDSA key fingerprint is 5 ...