前提
平时使用都是使用tomcat来部署服务的,然后最近升级了tomcat之后,发现了一个Url传参的功能不能用了,然后再仔细一看,乱码了!由于产品的代码都是没改过的,唯一的变量就是tomcat版本了,所以去官网看看tomcat升级是不是做了什么改变
排查原因
首先先看返回的错误为:
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:467)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:667)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:789)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
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)
其实报错也说的很明显的了 The valid characters are defined in RFC 7230 and RFC 3986
说明我传递的是无效字符,但是我一直没动过,怎么可能会有无效字符呢?
此时去看tomcat的改变日志:https://tomcat.apache.org/tomcat-8.5-doc/changelog.html,发现了一个原因:
那原因其实就很明显了:tomcat升级8的时候,对url中的请求参数增加了限制,如果是不满足 RFC 7231规定的字符的话,则直接返回400
解决方案
其实解决方案很简单,主要是归根于四种解决方案
1、url使用base64传递参数,然后服务器解析base64
2、设置 “ relaxedQueryChars“ 属性,使你的字符能通过,具体可看https://stackoverflow.com/questions/41053653/tomcat-8-is-not-able-to-handle-get-request-with-in-query-parameters/51212677#51212677
3、设置 “requestTargetAllow“属性 https://stackoverflow.com/questions/41053653/tomcat-8-is-not-able-to-handle-get-request-with-in-query-parameters/44005213#44005213
4、回退tomcat版本