简体   繁体   English

Java Web Service返回带有>和<而不是>和的字符串

[英]Java Web Service returns string with &gt; and &lt; instead of > and <

I have a java web service that returns a string. 我有一个返回字符串的java Web服务。 I'm creating the body of this xml string with a DocumentBuilder and Document class. 我正在使用DocumentBuilderDocument类创建此xml字符串的主体。 When I view source of the returned XML (Which looks fine in the browser window) instead of <> it's returning &lt; 当我查看返回的XML的源代码(在浏览器窗口中看起来很好)而不是<>它返回&lt; and &gt; &gt; around the XML nodes. 围绕XML节点。

Please help. 请帮忙。

****UPDATE (including code example) ****更新(包括代码示例)
The code is not including any error catching, it was stripped for simplicity. 代码不包括任何错误捕获,为简单起见,它被剥离。 One code block and three methods are included: The first code block (EXAMPLE SETUP) shows the basics of what the Document object is setup to be like. 包含一个代码块和三个方法:第一个代码块(示例设置)显示了Document对象设置的基础知识。 the method appendPayment(...) is where the actual document building happens. 方法appendPayment(...)是实际文档构建发生的地方。 It calls on two helper methods getTagValue(...) and prepareElement(...) 它调用了两个辅助方法getTagValue(...)prepareElement(...)
**Note, this code is meant to copy specific parts from a pre-existing xml string, xmlString , and grap the necessary information to be returned later. **注意,此代码用于从预先存在的xml字符串xmlString复制特定部分,并获取稍后要返回的必要信息。

****UPDATE 2 Response added at the end of the question ****更新2在问题结尾处添加了回复

************ Follow-up question to the first answer is here: ************第一个答案的后续问题在这里:
How to return arbitrary XML Document using an Eclipse/AXIS2 POJO Service 如何使用Eclipse / AXIS2 POJO服务返回任意XML文档

EXAMPLE SETUP
{
    //create new document
    DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder newDocBuilder = docFactory.newDocumentBuilder();
    Document newDoc = newDocBuilder.newDocument();
    Element rootElement = newDoc.createElement("AllTransactions");

    newDoc.appendChild(rootElement);
    appendPayment(stringXML, newDoc);
}

public static void appendPayment(String xmlString, Document newDoc) throws Exception
{
    //convert string to inputstream
    ByteArrayInputStream bais = new ByteArrayInputStream(xmlString.getBytes());
    DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
    Document oldDoc =   docBuilder.parse(bais);
    oldDoc.getDocumentElement().normalize();            

    NodeList nList = oldDoc.getChildNodes();
    Node nNode = nList.item(0);
    Element eElement = (Element) nNode;

    //Create new child node for this payment
    Element transaction = newDoc.createElement("Transaction");
    newDoc.getDocumentElement().appendChild(transaction);


    //status
    transaction.appendChild(prepareElement("status", eElement, newDoc));

    //amount
    transaction.appendChild(prepareElement("amount", eElement, newDoc));
}

private static String getTagValue(String sTag, Element eElement)
{
    NodeList nlList = eElement.getElementsByTagName(sTag).item(0).getChildNodes();
    Node nValue = (Node) nlList.item(0);
    return nValue.getNodeValue();
}

private static Element prepareElement(String sTag, Element eElement, Document newDoc)
{
    String str = getTagValue(sTag, eElement);
    Element newElement = newDoc.createElement(sTag);
    newElement.appendChild(newDoc.createTextNode(str));
    return newElement;
}

Finally, I use the following method to convert the final Document object to a String 最后,我使用以下方法将最终的Document对象转换为String

public static String getStringFromDocument(Document doc)
{
    try
    {
       DOMSource domSource = new DOMSource(doc);
       StringWriter writer = new StringWriter();
       StreamResult result = new StreamResult(writer);
       TransformerFactory tf = TransformerFactory.newInstance();
       Transformer transformer = tf.newTransformer();
       transformer.transform(domSource, result);
       return writer.toString();
    }
    catch(TransformerException ex)
    {
       ex.printStackTrace();
       return null;
    }
}

The header type of the response is as follows 响应的头类型如下

Server: Apache-Coyote/1.1
Content-Type: text/xml;charset=utf-8
Transfer-Encoding: chunked

This is an example response 这是一个示例响应

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
        <getTransactionsResponse xmlns="http://services.paypal.com">
        <getTransactionsReturn>&lt;AllTransactions&gt;&lt;Transaction&gt;&lt;status&gt;PENDING&lt;/status&gt;&lt;amount&gt;55.55&lt;/amount&gt;&lt;/transaction&gt;
        </getTransactionsResponse>
    </soapenv:Body>
</soapenv:Envelope>

The framework is doing what you tell it; 框架正在做你所说的; your method returns a String which means the generated WSDL should have a response message of type <xsd:string> . 您的方法返回一个String ,这意味着生成的WSDL应该有一个类型为<xsd:string>的响应消息。 As we know, XML strings must encode certain characters as character entity references (ie " < " becomes " &lt; " so the XML parser treats it as a string, not the beginning of an XML element as you intend). 我们知道,XML字符串必须将某些字符编码为字符实体引用 (即“ < ”变为“ &lt; ”,因此XML解析器将其视为字符串,而不是您想要的XML元素的开头)。 If you want to return an XML document then you must define the XML structure in the WSDL <types> section and set the response message part to the appropriate element. 如果要返回XML文档,则必须在WSDL <types>部分中定义XML结构,并将响应消息部分设置为相应的元素。

To put it another way, you are trying to send "typed" data without using the strong type system provided by SOAP/WSDL (namely XML schema); 换句话说,您尝试发送“类型化”数据而不使用SOAP / WSDL提供的强类型系统(即XML模式); this is generally regarded as bad design (see Loosely typed versus strongly typed web services ). 这通常被视为糟糕的设计(请参阅松散类型与强类型的Web服务 )。

The ultimate solution is to to define the response document via a proper XML Schema . 最终的解决方案是通过适当的XML Schema定义响应文档。 If there is no set schema, as by the design of your service, then use the <xsd:any> type for the message response type, although this approach has its pitfalls . 如果没有设置模式,例如服务的设计,那么使用<xsd:any>类型作为消息响应类型,尽管这种方法存在缺陷 Moreover, such a redesign implies a schema-first (top-down) development model and from the comment stream it seems that you are currently practicing code-first (bottom-up) approach. 此外,这样的重新设计意味着模式优先(自上而下)开发模型,并且从评论流看来,您似乎正在实践代码优先(自下而上)方法。 Perhaps your tools provide a mechanism such as a "general XML document" return type or annotation which achieves the same effect. 也许您的工具提供了一种机制,例如“常规XML文档”返回类型或注释,它们可以实现相同的效果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM