1. 程式人生 > >解決:Invalid character found in the request target.The valid characters are defined in RFC 7230 and RF

解決:Invalid character found in the request target.The valid characters are defined in RFC 7230 and RF

背景

在將tomcat升級到7版後,發現系統的有些功能不能使用了,查詢日誌發現是有些地址直接被tomcat認為存在不合法字元,返回HTTP 400錯誤響應,錯入資訊如下:

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.InternalInputBuffer.parseRequestLine(InternalInputBuffer.java:192)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1028)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:745)

原因分析

經瞭解,這個問題是高版本tomcat中的新特性:就是嚴格按照 RFC 3986規範進行訪問解析,而 RFC 3986規範定義了Url中只允許包含英文字母(a-zA-Z)、數字(0-9)、-_.~4個特殊字元以及所有保留字元(RFC3986中指定了以下字元為保留字元:! * ’ ( ) ; : @ & = + $ , / ? # [ ])。而我們的系統在通過地址傳參時,在url中傳了一段json,傳入的引數中有"{"不在RFC3986中的保留欄位中,所以會報這個錯。

根據(https://bz.apache.org/bugzilla/show_bug.cgi?id=60594) ,從以下版本開始,有配置項能夠關閉/配置這個行為: 8.5.x系列的:8.5.12 onwards 8.0.x系列的:8.0.42 onwards 7.0.x系列的:7.0.76 onwards

處理方法

…/conf/catalina.properties中,找到最後註釋掉的一行 #tomcat.util.http.parser.HttpParser.requestTargetAllow=|  ,改成tomcat.util.http.parser.HttpParser.requestTargetAllow=|{},表示把{}放行

------2018.01.30 新增-------- 按照上面的方法處理好後,在非IE瀏覽器上訪問,是沒有問題了。但若是在IE瀏覽器上進行訪問,這個錯誤還是會出現,在IE上訪問出現這個錯誤的原因:因為url的引數json中有雙引號,火狐和谷歌瀏覽器會自動對url進行轉碼,但IE不會

這種情況的處理方法: 給系統配置方向代理伺服器,通過反向代理伺服器進行urlrewrite,手動取出各個json的資料,手動將雙引號進行轉碼為%22:

具體方式如下: 編輯 Apache安裝目錄/conf/httpd.conf, 在配置MAS反向代理的前面新增如下資訊:

RewriteCond %{QUERY_STRING} json RewriteCond %{QUERY_STRING} !msKey RewriteCond %{QUERY_STRING} msInfo RewriteCond %{QUERY_STRING} player RewriteCond %{QUERY_STRING} {^a-zA-Z0-9[a-zA-Z0-9]:[^a-zA-Z0-9]([a-zA-Z0-9*]+)[a-zA-Z0-9],^a-zA-Z0-9[a-zA-Z0-9]:[^a-zA-Z0-9]([a-zA-Z0-9*]+)[a-zA-Z0-9]} RewriteRule ^(.*)? $1?method=sendJson&json={%22%1%22:%22%2%22,%22%3%22:%22%4%22} [R,L,NE]

參考