终极解决方案: 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

25-Aug-2018 11:27:27.086 信息 [http-nio-8087-exec-5] org.apache.coyote.http11.Http11Processor.service Error parsing HTTP request header
 Note: further occurrences of HTTP header parsing errors will be logged at DEBUG level.
 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)

从错误日志中看到Error parsing HTTP request header
负责解析http请求的是org.apache.tomcat.util.http.parser.HttpParser,它对请求对URL中对字符做了限制,具体代码如下:
IS_NOT_REQUEST_TARGET[]中定义了一堆not request target

if(IS_CONTROL[i] || i > 127 || i == 32 || i == 34 || i == 35 || i == 60 || i == 62 || i == 92 || i == 94 || i == 96 || i == 123 || i == 124 || i == 125) {
                IS_NOT_REQUEST_TARGET[i] = true;
            }

转换过来就是以下字符(对应10进制ASCII),也就是URL中不能包含的特殊字符:

  • 键盘上那些控制键:(<32或者=127)
  • 非英文字符(>127)
  • 空格(32)
  • 双引号(34)
  • #(35)
  • <(60)
  • >(62)
  • 反斜杠(92)
  • ^(94)
  • TAB上面那个键,~(96)
  • {(123)
  • }(124)
  • |(125)



我碰到这个问题也捣弄了半天,参照其他的各种解决方案都不行。并且我是使用了多种特殊字符,运用单一某种方案还不能完全奏效。下面是经过实践的解决方案,请按顺序读完。

解决办法(亲测)

在conf/catalina.properties中最后添加2行:

tomcat.util.http.parser.HttpParser.requestTargetAllow=|{}
org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true

该方式,在所有Tomcat版本均适用。

解析:在执行请求时,碰到该没问题的,大多是在URL中传输Json等。尤其是用浏览器地址输入的URL死活不能包含有任何特殊字符。否则会返回400 状态码。

首先:不推荐降低tomcat版本,这等于掩耳盗铃,绝对得不偿失。
Tomcat在 7.0.73, 8.0.39, 8.5.7 版本后,在http解析时做了严格限制。
RFC3986文档规定,请求的Url中只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~4个特殊字符以及所有保留字符。

如果要使用这些特殊字符,并不是绝对不可以。Tomcat做了限制的同时,也提供了相关配置。给出的解决方案第一行requestTargetAllow,指定了允许的特殊字符,在等号后面配|{}就行了。

如果你需要使用这三个字符,配置到此就OK了。重启tomcat,rebuild工程再启动,就能正常使用了。

不幸的是, requestTargetAllow 只能配置|、{、} 允许这三个字符,对于其他的(例如" < > [ \ ] ^ ` { | } .),在请求时,仍然拦截,如果使用了|{}之外的其他字符那怎么办呢?那就还需要如下配置。

在conf/server.xml中的<Connector>节点中,添加2个属性:

relaxedPathChars="|{}[],"
relaxedQueryChars="|{}[],"

这2个属性,可以接收任意特殊字符的组合,根据需要可以自行增减。
与此相关的文档说明:


文档地址:https://tomcat.apache.org/tomcat-8.5-doc/config/systemprops.html


 


文档地址:https://tomcat.apache.org/tomcat-8.5-doc/config/http.html


 

 


文档地址:http://tomcat.apache.org/tomcat-7.0-doc/changelog.html





另一种方式,就是发请求前,进行URLEncoder.encode(requestURI,"UTF-8");此方法适用于 执行发出请求的是ajax或其他客户端程序(可以发出http请求的编程语言,都有encode()相关支持)。

 

然后在后台接收请求后decode()
String params = request.getParameter(PARAMS);
params = URLDecoder.decode(params,"UTF-8");

 

  • 50
    点赞
  • 118
    收藏
    觉得还不错? 一键收藏
  • 30
    评论
java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986是一个Java异常,它表示在请求目标中找到了无效字符。RFC 7230和RFC 3986定义了请求目标中允许的有效字符范围。这个异常通常出现在HTTP请求的处理过程中。 出现这个异常的原因可能是由于请求目标中包含了不符合RFC标准的无效字符。可能是由于URL编码错误、特殊字符未正确转义等原因导致的。通常情况下,这个异常会记录在日志中,以帮助开发者定位问题。 解决这个问题的方法是确保请求目标中的字符都是符合RFC 7230和RFC 3986定义的有效字符范围。可以使用URL编码对特殊字符进行正确转义,确保请求目标的格式符合标准。另外,还可以检查代码中处理请求目标的部分,确保没有对无效字符进行处理或解析。 综上所述,java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986是一个Java异常,表示在请求目标中找到了无效字符。要解决这个问题,需要确保请求目标中的字符符合RFC标准,并且检查代码中处理请求目标的部分,确保没有对无效字符进行处理或解析。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [java.lang.IllegalArgumentException: Invalid character found in the request target 异常](https://blog.csdn.net/weixin_46417933/article/details/122409399)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [java.lang.IllegalArgumentException: Invalid character found in the request target. The valid charact](https://blog.csdn.net/ab601026460/article/details/85258829)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 30
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值