项目从原先的jdk1.6+tomcat6(6.0.26) 升级为jdk1.8+tomcat9(9.022)。升级完后在tomcat日志中发现经常会出现RFC 7230 and RFC 3986 这个错误。于是在网上搜集资料,做个总结。
首先出现这个问题是原因高版本的tomcat会严格按照对RFC 3986规范进行访问解析。
RFC 3986规范定义了Url中只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~4种特殊字符以及所有保留字符(RFC3986中指定了以下字符为保留字符:! * ’ ( ) ; : @ & = + $ , / ? # [ ])。而我们的系统在通过地址传参时,在url中传了一段参数包含有有不在RFC3986中的保留字段中,所以会报这个错。
解决方案:(这里就不推荐需要去改程序的做法了,从根源上解决才能高枕无忧)
1.换低版本的tomcat (tomcat 7.0.76之前的版本不会出现这个问题)
但是换低版本只是缓兵之计,肯定要从源头上来解决。而且在工作中想换项目的tomcat版本往往不是一个人能决定的。
2.修改tomcat目录底下的/conf/catalina.properties配置文件
想知道你所用的tomcat版本适不适用这个方法的话,可以用下面这个方法来鉴别:
查看catalina.properties文件中是否存在着下面这句话,没有就不用尝试了,说明这个版本不支持。
#tomcat.util.http.parser.HttpParser.requestTargetAllow=|
如果存在上面这句话就可以尝试去除#来开启该配置,然后在后面添加URL中可能会出现的非保留字符(就是你觉得你的URL中可能存在哪种特殊字符,填进去就完事了)
tomcat.util.http.parser.HttpParser.requestTargetAllow=|{}-
注:上面的{}-就是你填入想要非保留字符。
上面这种做法应该在tomcat7.076、tomcat8.042、tomcat8.512之后这些子版本才支持。tomcat9.022版本不支持(亲测)
3.修改tomcat目录底下的/conf/server.xml (能看到第三个方法估计就是前二个方法不管用了,没错,我就是)
打开tomcat目录底下/conf/server.xml
往Connector中添加relaxedQueryChars和relaxedPathChars,直接复制下面的relaxedQueryChars和relaxedPathChars即可。
<Connector port="xxx" relaxedQueryChars="[]|{}-^`"<>"relaxedPathChars="[]|{}-^`"<>"
注:其中的` " < > 分别代表 \ ` < > 四种符号
第三种方法用tomcat9.022版本亲测是成功的。
总结:
1.tomcat 7.062版本之前对RFC 3986规范不严格所以不会出现这个错误。
2.tomcat7.076、tomcat8.042、tomcat8.512之后的子版本可以尝试修改catalina.properties来解决这个问题。
3.tomcat9的版本就使用修改server.xml来解决这个问题。
4.在网上看到有人分享,说IE浏览器才会出现这个问题。但是我用谷歌之类的浏览器也是会出现的。
5.感谢评论区的大神做的补充:tomcat6 (6.0.51,6.0.48)也会出现这个问题,是因为CVE-2017-5647这个漏洞,详细可以看看评论区,里面有从源码解释为什么该版本不支持。
6.在网上看到改成post请求也能解决,不过涉及到改程序了,这里不做总结。