Spring Cloud 项目中须要使用这样的URL地址(http://localhost:19001/work.html?a=b|c),且由于某种不可告知的缘由不能进行URLEncode转换。
Spring Cloud报错:
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.
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.
at
at
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.
at
RFC3986文档规定,Url中只容许包含英文字母(a-z,A-Z)、数字(0-9)、- _ . ~ 4个特殊字符以及全部保留字符。
指定了如下字符为保留字符:! * ’ ( ) ; : @ & = + $ , / ? # [ ]
解决方法是修改tomcat的catalina.properties 配置:
tomcat.util.http.parser.HttpParser.requestTargetAllow=|{}
但是咱们是Spring Cloud啊,哪有这个配置文件啊。
查看源码发现读取了系统环境变量tomcat.util.http.parser.HttpParser.requestTargetAllow(略过其中查找Spring配置、查找tomcat-embed-core-8.5.23.jar修改里面配置等等步骤)。
String prop = System.getProperty("tomcat.util.http.parser.HttpParser.requestTargetAllow");
int i;
if (prop != null) {
for(i = 0; i < prop.length(); ++i) {
char c = prop.charAt(i);
if (c != '{' && c != '}' && c != '|') {
log.warn(sm.getString("httpparser.invalidRequestTargetChar
acter", new Object[]{c}));
} else {
REQUEST_TARGET_ALLOW[c] = true;
}
}
}
在启动时增长VM参数
-Dtomcat.util.http.parser.HttpParser.requestTargetAllow=|{}
搞定!
补完:
后来发如今shell里启动时保留字符也出现问题,启动脚本没法传入,最后直接在Application里经过代码直接设置系统属性搞定。
System.setProperty("tomcat.util.http.parser.HttpParser.requestTargetAllow","|{}");