SpringBoot內(nèi)嵌tomcat處理有特殊字符轉(zhuǎn)義的問題
SpringBoot內(nèi)嵌tomcat處理有特殊字符轉(zhuǎn)義
前段時(shí)間在發(fā)生了前端調(diào)后臺(tái)接口失敗,原因是url中存在特殊字符,SpringBoot自帶的tomcat無法正常解析,返回400 bad Request。
網(wǎng)上搜了一下,發(fā)現(xiàn)是因?yàn)閠omcat高版本中,更加嚴(yán)格按照 RFC 3986規(guī)范進(jìn)行訪問解析,而 RFC 3986規(guī)范規(guī)定Url中只允許包含英文字母(a-zA-Z)、數(shù)字(0-9)、-_.~4個(gè)特殊字符以及所有保留字符(RFC3986中指定了以下字符為保留字符:! * ’ ( ) ; : @ & = + $ , / ? # [ ])。。
在這里記錄一下解決過程。
SpringBoot版本為 2.2.5release(不同版本的解決方式可能不同)。
實(shí)際解決方式(針對(duì)于使用SpringBoot內(nèi)置的Tomcat)
添加下面的配置Bean。
? ? /** ? ? ?* 配置轉(zhuǎn)義字符,解決當(dāng)請(qǐng)求路徑中特殊字符,高版本tomcat解析失敗的問題 ? ? ?*/ ? ? @Bean ? ? public ServletWebServerFactory webServerFactory() { ? ? ? ? TomcatServletWebServerFactory fa = new TomcatServletWebServerFactory(); ? ? ? ? fa.addConnectorCustomizers(connector -> { ? ? ? ? ? ? connector.setProperty("relaxedQueryChars", "(),/:;<=>?@[\\]{}"); ? ? ? ? ? ? connector.setProperty("rejectIllegalHeader", "false"); ? ? ? ? }); ? ? ? ? return fa; ? ? }
(該內(nèi)容只是用于記錄,具體是否有效沒有測(cè)試過)如果你不是使用SpringBoot的tomcat啟動(dòng)項(xiàng)目,那你就需要在tomcat的配置文件中添加以下配置信息,并重新啟動(dòng)。
org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true
Springboot2中修改tomcat參數(shù)支持請(qǐng)求特殊符號(hào)
解決:java.lang.IllegalArgumentException: Invalid character found in ...
使用Springboot2中內(nèi)置的tomcat啟動(dòng)項(xiàng)目時(shí)候,前端發(fā)來的請(qǐng)求報(bào)錯(cuò):
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:488) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:260) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.33.jar:9.0.33]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat-embed-core-9.0.33.jar:9.0.33]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1594) [tomcat-embed-core-9.0.33.jar:9.0.33]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.33.jar:9.0.33]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_144]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_144]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.33.jar:9.0.33]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_144]
這段報(bào)錯(cuò)的意思是:請(qǐng)求中含有無效字符,有效的字符在RFC 7230和RFC 3986中定義
出現(xiàn)這個(gè)錯(cuò)誤的原因是:我們?cè)谇昂笈_(tái)交互的時(shí)候請(qǐng)求的參數(shù),其中含有“{}”“[]”這些特殊符號(hào),在高版本的tomcat中含有這些字符的請(qǐng)求會(huì)被攔截。
例如:http://localhost:8080/sendMail?content=[1007]...
解決方法
springboot項(xiàng)目中增加一個(gè)配置,將webServerFactory方法加入到springboot啟動(dòng)類中,配置文件代碼如下:
import org.apache.catalina.connector.Connector; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class TomcatConfig { ? ? @Bean ? ? public TomcatServletWebServerFactory webServerFactory() { ? ? ? ? TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(); ? ? ? ? factory.addConnectorCustomizers((Connector connector) -> { ? ? ? ? ? ? connector.setProperty("relaxedPathChars", "\"<>[\\]^`{|}"); ? ? ? ? ? ? connector.setProperty("relaxedQueryChars", "\"<>[\\]^`{|}"); ? ? ? ? }); ? ? ? ? return factory; ? ? } }
這樣就解決問題啦!
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Springboot @Configuration @bean注解作用解析
這篇文章主要介紹了springboot @Configuration @bean注解作用解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-02-02java中的編碼轉(zhuǎn)換過程(以u(píng)tf8和gbk為例)
這篇文章主要介紹了java中的編碼轉(zhuǎn)換過程(以u(píng)tf8和gbk為例),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04java正則表達(dá)式處理花括號(hào)內(nèi)容替換賦值問題
這篇文章主要介紹了java正則表達(dá)式處理花括號(hào)內(nèi)容替換賦值問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05Springboot整合Flowable6.x導(dǎo)出bpmn20的步驟詳解
這篇文章主要介紹了Springboot整合Flowable6.x導(dǎo)出bpmn20,Flowable流程引擎可用于部署B(yǎng)PMN 2.0流程定義,可以十分靈活地加入你的應(yīng)用/服務(wù)/構(gòu)架,本文給出兩種從flowable導(dǎo)出流程定義bpmn20.xml的方式,需要的朋友可以參考下2023-04-04SpringBoot3集成ElasticSearch的方法詳解
Elasticsearch是一個(gè)分布式、RESTful風(fēng)格的搜索和數(shù)據(jù)分析引擎,適用于各種數(shù)據(jù)類型,數(shù)字、文本、地理位置、結(jié)構(gòu)化數(shù)據(jù)、非結(jié)構(gòu)化數(shù)據(jù),本文給大家詳解介紹了SpringBoot3集成ElasticSearch的方法,需要的朋友可以參考下2023-08-08Java創(chuàng)建型設(shè)計(jì)模式之工廠方法模式深入詳解
工廠方法模式(FACTORY METHOD)是一種常用的類創(chuàng)建型設(shè)計(jì)模式,此模式的核心精神是封裝類中變化的部分,提取其中個(gè)性化善變的部分為獨(dú)立類,通過依賴注入以達(dá)到解耦、復(fù)用和方便后期維護(hù)拓展的目的。它的核心結(jié)構(gòu)有四個(gè)角色,分別是抽象工廠、具體工廠、抽象產(chǎn)品、具體產(chǎn)品2022-09-09Spring?JPA的實(shí)體屬性類型轉(zhuǎn)換器并反序列化工具類詳解
這篇文章主要介紹了Spring?JPA的實(shí)體屬性類型轉(zhuǎn)換器并反序列化工具類詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02