是什么导致Tomcat中EOF或者isHexDigit消息出现java.io.CharConversionException?

时间:2020-03-06 14:27:48  来源:igfitidea点击:

这个异常使我们的生产Catalina日志更加简单地调用了" getParameter()"调用。

WARNING: Parameters: Character decoding failed. Parameter skipped.

java.io.CharConversionException: EOF
    at org.apache.tomcat.util.buf.UDecoder.convert(UDecoder.java:82)
    at org.apache.tomcat.util.buf.UDecoder.convert(UDecoder.java:48)
    at org.apache.tomcat.util.http.Parameters.urlDecode(Parameters.java:411)
    at org.apache.tomcat.util.http.Parameters.processParameters(Parameters.java:393)
    at org.apache.tomcat.util.http.Parameters.processParameters(Parameters.java:509)
    at org.apache.tomcat.util.http.Parameters.handleQueryParameters(Parameters.java:266)
    at org.apache.catalina.connector.Request.parseParameters(Request.java:2361)
    at org.apache.catalina.connector.Request.getParameter(Request.java:1005)
    at org.apache.catalina.connector.RequestFacade.getParameter(RequestFacade.java:353)
    at javax.servlet.ServletRequestWrapper.getParameter(ServletRequestWrapper.java:158)

或者有时:

java.io.CharConversionException: isHexDigit
    at org.apache.tomcat.util.buf.UDecoder.convert(UDecoder.java:87)
    at org.apache.tomcat.util.buf.UDecoder.convert(UDecoder.java:48)
    at org.apache.tomcat.util.http.Parameters.urlDecode(Parameters.java:411)
    at org.apache.tomcat.util.http.Parameters.processParameters(Parameters.java:393)
    at org.apache.tomcat.util.http.Parameters.processParameters(Parameters.java:509)
    at org.apache.tomcat.util.http.Parameters.handleQueryParameters(Parameters.java:266)
    at org.apache.catalina.connector.Request.parseParameters(Request.java:2361)
    at org.apache.catalina.connector.Request.getParameter(Request.java:1005)
    at org.apache.catalina.connector.RequestFacade.getParameter(RequestFacade.java:353)
    at javax.servlet.ServletRequestWrapper.getParameter(ServletRequestWrapper.java:158)

解决方案

只是在这里假设。似乎参数或者其值的URL解码失败(URL编码表示使用%XX或者%XXXX表示法对某些字符进行编码,其中XX或者XXXX是ISO-8859-1或者Unicode中字符的十六进制代码)。在第一种情况下,可能会发生错误,因为%字符后没有足够的十六进制字符。在第二种情况下,可能会发生这种情况,因为%字符之后的字符不是十六进制。

要调查的另一件事是Tomcat"连接器"配置中的URIEncoding。如果链接位于UTF-8编码的页面中,它将使用UTF-8将URL编码为字节,然后URL编码需要它的任何字节。但是,默认情况下,Tomcat认为这些字节是ISO-8859-1,这可能会导致问题。

反之也可能成立:如果页面是ISO-8859-1,并且Tomcat的URIEncoding已设置为UTF-8,则可能会导致类似的错误。

这是有关此领域问题的有用讨论:JSP / Servlet容器中的字符集陷阱

也可能是这样(来自Wikipedia):

存在Unicode字符的非标准编码:%uxxxx,其中xxxx是表示为四个十六进制数字的Unicode值。任何RFC均未指定此行为,并且已被W3C拒绝。 ECMA-262的第三版仍然包括使用此语法的转义(string)函数,还包括可转换为UTF-8并对每个八位位组进行百分比编码的encodeURI(uri)函数。

因此,我们可能会在Javascript中使用旧的转义函数,但是由于Tomcat的更高版本对此事更加严格(5.5.17,请对该编码进行滑动),因此仅现在我们才开始看到异常。

当用户通过ajax请求发送"%"时,我开始收到此错误。事实证明,我在提出请求之前并没有转义参数。此博客文章涵盖了此场景和修复的完整记录。