相关文章推荐
大力的牛肉面  ·  npm ERR! code E503 ...·  1 月前    · 
有胆有识的自行车  ·  svn ...·  1 年前    · 
深情的小刀  ·  c++ - MFC BitBlt and ...·  1 年前    · 

Tomcat8.5,当Get请求中包含了未经编码的中文字符时,会报以下错误,请求未到应用程序在Tomcat层就被拦截了。


Tomcat报错:


java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986


返回400错误:


Transfer-Encoding—>[chunked]\

null—>[HTTP/1.1 400 Bad Request]\

Server—>[Apache-Coyote/1.1]\

Connection—>[close]\

Date—>[Wed, 07 Feb 2018 03:19:04 GMT]


根据错误找到了Tomcat最新的源码:

iib.invalidRequestTarget=Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986


org/apache/coyote/http11/Http11InputBuffer.java

boolean parseRequestLine(boolean keptAlive) throws IOException {
    } else if (HttpParser.isNotRequestTarget(chr)) {
        throw new IllegalArgumentException(sm.getString("iib.invalidRequestTarget"));
}

java/org/apache/tomcat/util/http/parser/HttpParser.java

public static boolean isNotRequestTarget(int c) {
    // Fast for valid request target characters, slower for some incorrect
    // ones
    try {
        return IS_NOT_REQUEST_TARGET[c];
    } catch (ArrayIndexOutOfBoundsException ex) {
        return true;
}

查源码发现在Tomcat7.0.73就已经添加了RFC 3986这个规范。


RFC 3986文档对Url的编解码问题做出了详细的建议,指出了哪些字符需要被编码才不会引起Url语义的转变,以及对为什么这些字符需要编码做出了相应的解释。


RFC 3986文档规定,Url中只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~4个特殊字符以及所有保留字符(! * ’ ( ) ; : @ & = + $ , / ? # [ ])。


还有一些字符当直接放在Url中的时候,可能会引起解析程序的歧义,这些字符被视为不安全字符。


空格:Url在传输的过程,或者用户在排版的过程,或者文本处理程序在处理Url的过程,都有可能引入无关紧要的空格,或者将那些有意义的空格给去掉。

引号以及<>:引号和尖括号通常用于在普通文本中起到分隔Url的作用

#:通常用于表示书签或者锚点

%:百分号本身用作对不安全字符进行编码时使用的特殊字符,因此本身需要编码

{}|\^[]`~:某一些网关或者传输代理会篡改这些字符

对于此问题,有以下几种解决方案。


1、切换版本到7.0.73以下,这个不实际。


2、修改Tomcat源码,这个也不实际。


3、前端请求对URL编码。


4、修改Get方法为Post方法。


5、因{}是不安全字符,默认被 tomcat拦截。如果需要在URL中传输json数据,在catalina.properties中添加支持。


tomcat.util.http.parser.HttpParser.requestTargetAllow=|{}


总结


如果Get请求在合作方,而合作方不愿意修改代码,那1、2种方法可以尝试。如果Get请求在自己,可以尝试3、4种方法。仅需要在URL上传输json数据,使用第5种方法即可。


某Java程序员在外包公司每天读写删改几年后,发现跳不出来了
面试了一波Java程序员,有好几位80后的。按理说,他们有将近十年的工作开发时间,无论经验还是技术都应该称得上老司机了。着重考察了Spring中bean的后置处理器相关问题,大概是这样问的:
Java 后端学习路线;程序员是否一定要参与开源;为什么好多大网站用了 vue/react 还在用 jQuery |极客观点
Java 后端学习路线;程序员是否一定要参与开源;为什么好多大网站用了 vue/react 还在用 jQuery |极客观点
惊艳!Alibaba内部流行的“Java突击宝典”,程序员升职加薪必备
Alibaba作为一线互联网公司的代表,是大部分程序员梦寐以求的工作场所,确实大厂出来的程序员,其背景也更值钱,含金量也会更高。实际上,Alibaba程序员早已成为行业内学习的榜样和标杆,但实际上光鲜的背后付出的血汗是我们没看到的。那么阿里程序员平常都是怎么学习的呢?
进阶面试皆宜!阿里强推Java程序员进阶笔记,差距不止一点点
程序员要如何成长这个问题,一直是各大网站、论坛的热点。对此网络上众说纷纭,一千个读者里面就有一千个哈姆雷特。LZ觉得想要让个人技能成长速度,大于公司规模或业务的成长速度,不断优化自己,成为一名“不错”的程序员主要需要掌握以下学习方法与实战技巧。
年薪120W的架构师简历你见过吗?java程序员该如何达到?
第一个问题是,“大多数Java开发人员都在哪里,我们中有多少人?”我们回答了这个问题,把我们能得到的最准确的信息结合起来,然后推断出我们认为是一个受过良好教育的猜测。
最壕逆天改命:18名Java程序员凭阿里P8笔记,同时斩获大厂offer
上高中时由于看了一本《坏蛋怎么练成的》从此一发不可收拾,对小说的痴迷渐渐成了病态,上课看下课看,成绩一落千丈,还好高三幡然醒悟勉勉强强上了一个“野鸡”二本,学了所有男生都喜欢的计算机专业;