【问题标题】:Escaping entire XML for a webservice response为 Web 服务响应转义整个 XML
【发布时间】:2015-02-13 16:16:52
【问题描述】:

我有一个 Java Restful web 服务,它返回一个 userdetails xml,如下所示:

<userdetails>
    <firstName>first</firstName>
    <firstName>last</firstName>
    <email>123@gmail.com</email>
</userdetails>

XML 中的任何字段都可以包含特殊字符,当客户端使用 Jaxb 将 xml 转换为 java 对象时,这会导致客户端出现问题。

我可以使用“StringEscapeUtils.escapeXml”来转义字段中的特殊字符,例如为 firstName 说的,并且它正在正确地转义它。

StringEscapeUtils.escapeXml(firstName);

但我必须对我的 XML 中的每个字段都这样做。有什么方法可以一次转义整个 XML,而不是对每个字段都进行转义。

【问题讨论】:

  • 任何 xml 编码器都应该自动为您处理转义。
  • 一直在使用 jaxb 进行编组和解组......它不会在服务器端抱怨......但在客户端,在解组期间注意到具有这些特殊字符的字段的问题
  • 什么问题?客户端如何解析xml?
  • 客户端也在使用 jaxb....所以当他们尝试将 xml 解组为 java 对象时,他们会看到这些特殊字符的问题
  • 他们看到了什么问题?

标签: java xml web-services rest jakarta-ee


【解决方案1】:

另一种选择是遍历所有文本元素,在此过程中将它们转义(以下代码取自here 并稍作修改):

import java.io.File;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.apache.commons.lang.StringEscapeUtils;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

public class EscapeXml {
  static String inputFile = "data.xml";
  static String outputFile = "data_new.xml";

  public static void main(String[] args) throws Exception {
    Document doc = DocumentBuilderFactory.newInstance()
              .newDocumentBuilder().parse(new InputSource(inputFile));

    // locate the node(s)
    XPath xpath = XPathFactory.newInstance().newXPath();
    NodeList nodes = (NodeList)doc.getElementsByTagName("*");

    // escape text nodes
    for (int idx = 0; idx < nodes.getLength(); idx++) {
      Node node = nodes.item(idx);
      if (node.getNodeType() == Node.ELEMENT_NODE) {
        NodeList childNodes = node.getChildNodes();
        for (int cIdx = 0; cIdx < childNodes.getLength(); cIdx++) {
          Node childNode = childNodes.item(cIdx);
          if (childNode.getNodeType() == Node.TEXT_NODE) {
            String newTextContent =  
              StringEscapeUtils.escapeXml(childNode.getTextContent());                
            childNode.setTextContent(newTextContent);
          }
        }
      }
    }

    // save the result
    Transformer xformer = TransformerFactory.newInstance().newTransformer();
    xformer.transform(new DOMSource(doc), new StreamResult(new File(outputFile)));
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-28
    相关资源
    最近更新 更多