Tomcat請求特殊字符參數問題:Invalid character found in the request target. The valid characters are defined in

一、問題錯誤

最近遇到客戶端說接口get請求,全部400錯誤,無法請求,剛開始以爲是服務器對請求進行攔截了,但是訪問主頁面是正常的,也是get請求,那麼可能就是tomcat的問題了,想到tomcat8的原因,會不會是請求參數的問題,後來url請求中包含{}[]特殊字符的都報錯,是因爲Tomcat在 7.0.73, 8.0.39, 8.5.7版本後,在http解析時做了嚴格限制。

tomcat8正常訪問:
在這裏插入圖片描述
後臺報錯原因:

 java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
 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:745)

在這裏插入圖片描述
前臺報錯:

http://192.168.2.25:8080/hg/check/list?data={"userid":"6"} 
Failed to load resource: the server responded with a status of 400 (Bad Request)

在這裏插入圖片描述

二、問題分析

在使用tomcat8中,我們可以看到錯誤java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986,也就是說我們的請求中包含無效的字符,由RFC規範可以得知,url中只允許包含英文字母(a-zA-Z)數字(0-9)-_.~四個特殊字符由於我們請求中包含{}字符串,所以tomcat報錯。

三、問題解決

1、不使用特殊字符:使用其他的常用字符或數字,但是對於一些特定的參數,是需要進行傳入特殊字符的——(不建議使用
2、對請求URL編碼解碼URLEncoder.encode(str,"UTF-8");URLDecoder.decode(str,"UTF-8");,這種方法對於單一的請求還是可以的,或者在項目結構開始時,統一使用這種方式(可以使用
3、配置Tomcat對特殊字符的支持:統一配置tomcat配置文件,在所有Tomcat版本均適用。(推薦使用

我們在conf/catalina.properties中最後添加2行,(親測有效

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

在這裏插入圖片描述

雖然Tomcat做了限制的同時,也提供了相關配置。給出的解決方案第一行requestTargetAllow,指定了允許的特殊字符,在等號後面配|{}就行了。

如果你只是需要使用這三個字符的話,使用上面的配置就可以使用了,重啓tomcat,啓動項目,就能正常使用了。

訪問成功:
在這裏插入圖片描述
但是由於項目經常會傳遞數組類型的數據,或者其他特殊字符串類型,但是requestTargetAllow只能配置|{}允許這三個字符,如果想要使用除了|{}這三個字符以外其他的(< > [ \ ] ^ ` { | } .)的字符串,我們需要以下配置:

conf/server.xml中的<Connector>節點中,添加2個屬性:

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

完整版:

 <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" 
	       URIEncoding="UTF-8"
               useBodyEncodingForURI="true"
		relaxedPathChars="|{}[],"
	 	relaxedQueryChars="|{}[],"
	/>

添加了這2個屬性,重啓tomcat後,訪問項目時,我們就可以使用任意特殊字符,方便快捷,而且不需要大規模的進行改動。

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章