encoding - Jetty Utf8Appendable$NotUtf8Exception on ISO-8859 Request with Spring

标签 encoding jetty

远程服务使用 ISO-8859-15 编码的请求调用我们的 Jetty 服务器。这个特殊的请求被映射到一个 Spring Controller 上。 Jetty 无法以正确的方式对请求进行编码,并显示以下异常:

exception=org.eclipse.jetty.util.Utf8Appendable$NotUtf8Exception: Not valid UTF8! byte F6 in state 3}
org.eclipse.jetty.util.Utf8Appendable$NotUtf8Exception: Not valid UTF8! byte F6 in state 3
    at org.eclipse.jetty.util.Utf8Appendable.appendByte(Utf8Appendable.java:168) ~[na:na]
    at org.eclipse.jetty.util.Utf8Appendable.append(Utf8Appendable.java:93) ~[na:na]
    at org.eclipse.jetty.util.UrlEncoded.decodeUtf8To(UrlEncoded.java:506) ~[na:na]
    at org.eclipse.jetty.util.UrlEncoded.decodeTo(UrlEncoded.java:554) ~[na:na]
    at org.eclipse.jetty.server.Request.extractParameters(Request.java:285) ~[na:na]
    at org.eclipse.jetty.server.Request.getParameter(Request.java:695) ~[na:na]
    ....

解决方案

在 Spring 中,即使整个应用程序使用 UTF-8,也可以通过 CharacterEncodingFilter 强制对请求进行编码。异常应该消失。
<filter>
    <filter-name>encoding-filter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>ISO-8859-15</param-value>
    </init-param>
    <init-param>
        <param-name>forceEncoding</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>encoding-filter</filter-name>
    <url-pattern>/app/specialRequest.do</url-pattern>
</filter-mapping>

如果这对您不起作用
  • 找出远程系统编码
  • 启动 Wireshark 通过 ip.src == xxx.xxx.xxx.xxx 过滤器分析传入的包
  • 在请求正文中搜索特殊字符(将十六进制值重新计算为二进制并尝试几种常用的编码以准确找到与异常匹配的编码)
  • 通过 Jetty 的 start.ini 设置编码,即。具有以下参数

    Dorg.eclipse.jetty.util.URI.charset=ISO-8859-15

    Dorg.eclipse.jetty.util.UrlEncoding.charset=ISO-8859-15

  • 否则,如果您有更多问题,请给我留言。

    最佳答案

    看起来客户端正在发送应该编码为 UTF8 的文本,但没有对其进行编码。

    为了正确诊断此问题,您需要了解 UTF8(您可能会这样做,我不知道)

    在 UTF8 中,任何编码为 127 (0x7F) 或更少的字符——即只使用最低的 7 位——都按原样包含在流中(没有特殊编码)。但是任何大于 127 的(即设置的至少比第 7 位高一位)都是经过特殊编码的。
    0xF6大于 0x7F因此,如果客户端想要发送该字符,则应对其进行编码。
    0xF6二进制是 11110110 , 在 UTF8 中应该是 11000011 10110110 ( C3 B6 )

    因此,如果客户端要发送 0xF6 的 ISO8859-1 字符,那么它应该发送 0xC3 0xB6 的 UTF8 字节序列。

    您确实需要弄清楚客户端想要发送什么,数据的字符集/编码是什么,以及为什么在发送之前不将其转换为有效的 UTF8。

    (“state 3”,是与Jetty的内部表做UTF8解码有关,对诊断这个问题真的不是很有帮助。只有找到客户端才会派上用场,看起来客户端做对了事情,你怀疑 Jetty 的 UTF8 解码是错误的)

    关于encoding - Jetty Utf8Appendable$NotUtf8Exception on ISO-8859 Request with Spring,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9136557/

    相关文章:

    python - 在 python 中使用 pdfminer 处理连字

    python - 使用 MySQLdb 对非 utf 符号进行 utf8 编码

    java - Dropwizard 线程等待计数增加,服务器停止响应所有资源请求

    java - 如何在 Dropwizard 中查看自定义 404 页面

    java - Jetty 9 - 为域验证证书启用 OCSP 装订

    java - 以错误的编码读取属性文件中的属性

    mysql - 提交到数据库后,输入字段保留空白并带有特殊字符

    java - Spring 和 PostgreSQL 之间的错误编码

    java - 从命令行启动 servlet 容器 (Jersey Jax RS)

    java - 嵌入式 Jetty 将 servlet 响应转发到 JSP