【问题标题】:Illegal character - CTRL-CHAR非法字符 - CTRL-CHAR
【发布时间】:2011-06-18 11:24:42
【问题描述】:

我从 web 服务收到以下异常:

com.ctc.wstx.exc.WstxUnexpectedCharException:非法字符((CTRL-CHAR,代码 15))

我知道这背后的原因,我在想要返回的数据中得到“控制字符”。并且在 XML 中 CTRL-CHAR 是不允许的。

我搜索了解决方法,很多地方都找到了删除CTRL-CHAR的代码。

问题是,如果我从数据中删除控制字符,我最终会丢失数据吗?
我希望干净的解决方案可以编码,而不是删除控制字符。

【问题讨论】:

  • 如果您要发送二进制数据,则不应使用 xml。
  • @sarnold : 十进制,忘记添加相关信息了。
  • @OrangeDog :我没有发送二进制数据,而是从数据库返回纯文本。不知道如何,但它有控制字符。
  • 那你需要定位并修复那个问题,而不是把问题隐藏在另一层。

标签: java xml web-services character-encoding


【解决方案1】:

此错误是由 Woodstox XML 解析器引发的。 InputBootstrapper 类的源代码如下所示:

protected void reportUnexpectedChar(int i, String msg)
    throws WstxException
{
    char c = (char) i;
    String excMsg;

    // WTF? JDK thinks null char is just fine as?!
    if (Character.isISOControl(c)) {
        excMsg = "Unexpected character (CTRL-CHAR, code "+i+")"+msg;
    } else {
        excMsg = "Unexpected character '"+c+"' (code "+i+")"+msg;
    }
    Location loc = getLocation();
    throw new WstxUnexpectedCharException(excMsg, loc, c);
}

除了有趣的评论之外,Woodstox 正在 JDK 解析器之上执行一些额外的验证,并拒绝 ASCII 字符 15 为无效。

至于为什么会有那个角色,我们不能告诉你,它在你的数据中。同样,我们无法告诉您删除该字符是否会破坏任何内容,因为这又是您的数据。你只能自己建立。

【讨论】:

    【解决方案2】:

    如果您的文本数据中有控制字符,那么您需要从源头解决该问题。

    最可能的原因是不正确的通信编码(通常在数据库和应用程序之间)或未清理用户输入。

    【讨论】:

      【解决方案3】:

      我会按照 OrangeDog 的建议去做。但是,如果您想在代码中解决它,请尝试:

      replaceAll("[\\x00-\\x09\\x11\\x12\\x14-\\x1F\\x7F]", "")

      \\x12 是字符。

      【讨论】:

        【解决方案4】:

        感谢大家的投入。我正在分享解决方案可能对其他人有帮助。 要求不是清除 CONTROL CHAR,它也应该在 DB 中保持原样,并且一个 WS 通过 n/w 客户端发送它应该能够获得 CONTROL CHAR。所以我实现了如下代码:

        1. 在 Web 服务代码中使用 URLEncoder 对字符串进行编码。
        2. 在客户端使用 URLDecoder 对其进行解码

        下面分享示例代码和输出。
        示例代码:

        System.out.println("NewSfn");  
        System.out.println(URLEncoder.encode("NewSfn", "UTF-8"));  
        System.out.println(URLDecoder.decode("NewSfn", "UTF-8"));  
        

        输出:

        NewSfn  
        New%0FSfn  
        NewSfn 
        

        所以客户端会收到控制字符。

        编辑:Stack Exchange 没有在上面显示 CONTROL CHAR。 NewSfn 就是这样的New(CONTROL CHAR)Sfn

        【讨论】:

        • 对于我的情况,从 DB 数据中输入密钥符号到发送的 jax-ws 服务器。如果使用 URLEncoder.encode(DB_input, "UTF-8")); URLEncoder.decode(DB_output, "UTF-8"));不会丢失数据。
        • 为了说明目的,可以使用单独的字符来表示控制字符。在你的情况下,它会是␏。
        【解决方案5】:

        当我为某些参数传递空值时,我发现了同样的问题。我改为传递空值或扳手值,此错误消失了。

        【讨论】:

          【解决方案6】:

          我对@ssedano 的回答有点困惑,在我看来,他试图从 ASCII 表 0x00 到 0x1F 中查找所有控制字符,但 0x0A(新行)和 0x0D(回车)以及 0x7F(删除)除外,那么不会有正则表达式

          replaceAll("[\\x00-\\x09\\x0B\\x0C\\x0E-\\x1F\\x7F]", "")
          

          【讨论】:

          • 请看问题:“我想要干净的解决方案……而不是删除控制字符。”另请参阅已接受的答案。所以,这并不能回答这个问题。 (有了更高的声誉,您可以评论或编辑您所指的其他答案。或者,甚至在相同的基础上对其投反对票。)
          猜你喜欢
          • 1970-01-01
          • 2012-08-17
          • 1970-01-01
          • 2020-12-15
          • 2019-04-28
          • 1970-01-01
          • 2015-10-10
          • 1970-01-01
          相关资源
          最近更新 更多