【问题标题】:Java - Send a UTF-8 string via web service and XML that may contain illegal charactersJava - 通过 Web 服务和 XML 发送可能包含非法字符的 UTF-8 字符串
【发布时间】:2011-08-06 13:55:31
【问题描述】:

我有一个用 Java 编写的 Web 服务。我想以 XML 文件的形式发送一些字符串。但是这些字符串可能包含一些在 XML 中被识别为非法的字符。目前我用?替换所有这些,创建 XML 并通过网络发送它(到 Silverlight 应用程序)。但有时我得到的只是问号!所以我想在发送它们之前和之后以某种方式对这些字符串进行编码/解码以获得确切的字符串。这些字符串采用 UTF-8 编码。我正在使用这样的东西来创建 XML:

try{
    DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder docBuilder = docFactory.newDocumentBuilder();

    //root elements
    Document doc = docBuilder.newDocument();
    Element rootElement = doc.createElement("SearchResults");
    rootElement.setAttribute("count", Integer.toString(total));
    doc.appendChild(rootElement);

    for(int i = 0; i < results.size(); i++)
    {
        Result res = results.get(i);
        //title
        Element title = doc.createElement("Title");
        title.appendChild(doc.createTextNode(res.title));
        searchRes.appendChild(title);

        //...
    }
    //write the content into xml file
    TransformerFactory transformerFactory = TransformerFactory.newInstance();
    Transformer transformer = transformerFactory.newTransformer();
    DOMSource source = new DOMSource(doc);
    StringWriter sw = new StringWriter();
    StreamResult result =  new StreamResult(sw);
    transformer.transform(source, result);
    String ret = sw.toString();
    return ret;
}
catch(ParserConfigurationException pce){
    pce.printStackTrace();
}catch(TransformerException tfe){
    tfe.printStackTrace();
}
return null;

谢谢。

PS: 有些人说他们不明白我的问题,所以也许我说得不对,所以我试着用一个例子来澄清它。 假设我有一个项目数组。
每个项目有 3 个字符串。
这些字符串是 UTF-8 字符串(来自多种语言)。
我想通过 Java 中的 Web 服务将这些字符串发送到客户端。
客户端部分是 Silverlight。在 Silverlight 应用程序中,
我获取 XML,对其进行解析并使用 LinQ 从中提取数据,然后在我的 Silverlight 应用程序中使用该数据。
当我尝试转义字符时,Silverlight 中的解析器以某种方式抛出异常,说在调试后源字符串(XML 字符串)中存在非法字符我发现实际上存在非法字符但我不知道如何生成有保证的合法 XML 字符串。

编辑: 谢谢大家的支持。我真的很感激。
我解决了我的问题。
结果在我的代码中某处我产生了一个非法字符并将其附加到我的结果字符串中。
问题仍然存在(如何生成合法的 XML 文件,即使我提供了一些非法字符 - 请注意,我通过在生成 XML 之前消除非法字符解决了这个问题,所以我仍然想知道如果我想以某种方式发送结束了吗?)但是由于我的问题已经解决并且这里有很多答案,我想未来的读者可以抢先开始面对这个问题的旅程。
我没有时间,但我相信这些会有所帮助。
有很多答案和帮助,所以我无法选择其中一个作为我的具体答案。
但我必须选择其中之一。
我真诚地感谢所有的回复。

【问题讨论】:

  • 首先正确编码字符。一个好的方法是使用 -construction。
  • @Thorbjorn(抱歉,不是欧盟键盘)- 这是转义,而不是编码,它不会帮助像 0x01 这样的字符,这些字符在 XML 1.0 下是不允许的。
  • @Alireza - 我注意到您正在将输出转换为字符串,然后可能将其写入流。更好的方法(因为它避免了可能的编码错误)是将该流直接传递给转换器。
  • @Anon :在我的 Web 方法中,我返回此字符串(在上面的代码中为 ret)作为结果。我没明白你说的对不起:D
  • 为了调试它,我建议在将原始字符串转换为 XML 之前检查它们是否包含非法字符。如果他们不这样做,那么问题在于如何将字符串写入输出。

标签: c# java .net web-services utf-8


【解决方案1】:

如果您在 XML 中发送非字符数据(例如二进制数据),您可以使用 Base64 对它们进行编码。但我不确定我是否正确理解了您的问题。

也许您只是忘记使用 transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8") 以 UTF-8 编码您的 XML

【讨论】:

  • +1。任何其他形式的 XML 转义都不会让您在 XML 中出现像 '\0' 这样的字符。
  • 谢谢。这些不是二进制数据(它们是从网页中截取的一些字符串),我不知道如何在 Base64 中编码。你能给我一个小教程或例子吗?
  • 还有一件事,使用transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); 没有帮助。
  • Alireza,看看 [Apache Commons Codec] (commons.apache.org/codec)。
  • 您可以使用BCodec 编码方法。或类似this.
【解决方案2】:

不确定我是否理解您的问题,但也许您应该将数据包装在 CDATA 标记下,这样 XML 解析器就不会对其进行解析。这是来自 MSDN 的documentation

【讨论】:

【解决方案3】:

&lt;![CDATA[]]&gt; 包装内容。

更多信息在这里:http://www.w3schools.com/xml/xml_cdata.asp

【讨论】:

  • CDATA 在您不希望解析 XML 时是一种好方法(它是标签原始函数)。但由于他是从头开始构建 XML 以供使用,因此更推荐(并且同样简单)的方法是转义字符串。
  • CDATA 不允许您使用“非法”字符(例如 0x01、SOH)。它的存在是为了让您可以使用通常需要转义的字符,例如&lt;。但即便如此,它也不是特别有用。
【解决方案4】:

根据经验,我建议转义/取消转义 XML。 从Apache Commons LangStringEscapeUtils

【讨论】:

  • 我试过这样:desc.appendChild(doc.createTextNode(StringEscapeUtils.escapeXml(res.description)));,但在 silverlight 部分,当我使用它时:XDocument xmlStories = XDocument.Parse(xmlContent); 我得到一个异常,说 XML 中有一个非法字符!
  • 像 '\0' 这样的字符在 XML 中是非法的。没有办法逃避它们(缺少自定义编码 - 请参阅 JB Nizet 使用 Base64 的答案)。
【解决方案5】:

你应该试试 apache 的 StringEscapeUtils

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多