Java 无法从给定源创建信封,因为根元素未命名为 Envelope

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40470966/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 22:43:56  来源:igfitidea点击:

Unable to create envelope from given source because the root element is not named Envelope

javasoapremedy

提问by Martin Erlic

I have a SOAP request that I've tested in SoapUI. I successfully get the desired response.

我有一个已在 SoapUI 中测试过的 SOAP 请求。我成功地得到了想要的回应。

The problem in my code occurs when I'm testing whether or not the response was successful at if (isSuccessResponse(soapResponse)) {below:

当我在下面测试响应是否成功时,我的代码中出现了问题if (isSuccessResponse(soapResponse)) {

public static void main(String[] args) throws Exception {

 // Establish SOAP connection
 SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
 SOAPConnection soapConnection = soapConnectionFactory.createConnection();

 // Generate SOAP request
 SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(), namespaceURI);

 // Test to see if SOAP response is available
 System.out.print("SOAP Response:");
 System.out.println();
 soapResponse.writeTo(System.out);

 // Close connection
 soapConnection.close();

 if (isSuccessResponse(soapResponse)) {
  System.out.println("Success!");
 } else {
  System.out.println("Fault!");
 }

}

Success?

成功?

private static boolean isSuccessResponse(SOAPMessage soapResponse) throws Exception {
 NodeList responseNodes = soapResponse.getSOAPBody().getElementsByTagNameNS("*", "HelpDesk_QueryList_Service");

 if (responseNodes.getLength() == 1)
  return true;
 else
  return false;
}

Request:This code does in fact print out the correct request as it is identical to the working request in SoapUI. So why can't I get the related relevant information from the actual response? The printed response is the blank default response with all the of requisite headers but none of the desired information from my request:

请求:此代码实际上打印出正确的请求,因为它与 SoapUI 中的工作请求相同。那么为什么我无法从实际响应中获取相关的相关信息呢?打印的响应是带有所有必需标头的空白默认响应,但没有来自我的请求的所需信息:

private static SOAPMessage createSOAPRequest() throws Exception {
 MessageFactory messageFactory = MessageFactory.newInstance();

 // Create SOAP Message
 SOAPMessage soapMessage = messageFactory.createMessage();

 // Add request envelope, headers, and nodes from SOAP request 
 SOAPPart soapPart = soapMessage.getSOAPPart();

 // I used ? here for privacy reasons
 String xmlns = "?";
 String username = "?";
 String password = "?";
 String qualification = "'?";

 SOAPEnvelope envelope = soapPart.getEnvelope();
 envelope.addNamespaceDeclaration("urn", xmlns);

 SOAPHeader soapHeader = envelope.getHeader();
 SOAPElement authInfoElem = soapHeader.addChildElement("AuthenticationInfo", "urn");
 createElementAndSetText(authInfoElem, "userName", username);
 createElementAndSetText(authInfoElem, "password", password);

 SOAPBody soapBody = envelope.getBody();
 SOAPElement bodyElem = soapBody.addChildElement("HelpDesk_QueryList_Service", "urn");
 createElementAndSetText(bodyElem, "Qualification", qualification);

 MimeHeaders headers = soapMessage.getMimeHeaders();
 headers.addHeader("SOAPAction", xmlns + "/HelpDesk_QueryList_Service");

 // Save request
 soapMessage.saveChanges();

 // Print the request message
 System.out.print("SOAP Request:");
 System.out.println();
 soapMessage.writeTo(System.out);
 System.out.println();
 System.out.println();

 return soapMessage;
}

Error:I get the following error but I'm not sure why.

错误:我收到以下错误,但我不知道为什么。

Lis 07, 2016 6:10:34 ODP. com.sun.xml.internal.messaging.saaj.soap.SOAPPartImpl lookForEnvelope
SEVERE: SAAJ0514: Unable to create envelope from given source because the root element is not named Envelope
Lis 07, 2016 6:10:34 ODP. com.sun.xml.internal.messaging.saaj.soap.EnvelopeFactory createEnvelope
SEVERE: SAAJ0511: Unable to create envelope from given source
Exception in thread "main" com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Unable to create envelope from given source: 
    at com.sun.xml.internal.messaging.saaj.soap.EnvelopeFactory.createEnvelope(EnvelopeFactory.java:117)
    at com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPPart1_1Impl.createEnvelopeFromSource(SOAPPart1_1Impl.java:69)
    at com.sun.xml.internal.messaging.saaj.soap.SOAPPartImpl.getEnvelope(SOAPPartImpl.java:128)
    at com.sun.xml.internal.messaging.saaj.soap.MessageImpl.getSOAPBody(MessageImpl.java:1351)
    at com.xxxx.automation.remedy.RemedySOAPService.isSuccessResponse(RemedySOAPService.java:135)
    at com.xxxx.automation.remedy.RemedySOAPService.main(RemedySOAPService.java:52)
Caused by: com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Unable to create envelope from given source because the root element is not named "Envelope"
    at com.sun.xml.internal.messaging.saaj.soap.SOAPPartImpl.lookForEnvelope(SOAPPartImpl.java:154)
    at com.sun.xml.internal.messaging.saaj.soap.SOAPPartImpl.getEnvelope(SOAPPartImpl.java:121)
    at com.sun.xml.internal.messaging.saaj.soap.EnvelopeFactory.createEnvelope(EnvelopeFactory.java:110)
    ... 5 more

CAUSE:

com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Unable to create envelope from given source because the root element is not named "Envelope"
    at com.sun.xml.internal.messaging.saaj.soap.SOAPPartImpl.lookForEnvelope(SOAPPartImpl.java:154)
    at com.sun.xml.internal.messaging.saaj.soap.SOAPPartImpl.getEnvelope(SOAPPartImpl.java:121)
    at com.sun.xml.internal.messaging.saaj.soap.EnvelopeFactory.createEnvelope(EnvelopeFactory.java:110)
    at com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPPart1_1Impl.createEnvelopeFromSource(SOAPPart1_1Impl.java:69)
    at com.sun.xml.internal.messaging.saaj.soap.SOAPPartImpl.getEnvelope(SOAPPartImpl.java:128)
    at com.sun.xml.internal.messaging.saaj.soap.MessageImpl.getSOAPBody(MessageImpl.java:1351)
    at com.xxxx.automation.remedy.RemedySOAPService.isSuccessResponse(RemedySOAPService.java:135)
    at com.xxxx.automation.remedy.RemedySOAPService.main(RemedySOAPService.java

:52)

SOAP Response:

肥皂响应:

<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>
      <ns0:HelpDesk_QueryList_ServiceResponse xmlns:ns0="urn:XX:XXXX:HPD_IncidentInterface_WS">
         <ns0:getListValues>
            <ns0:Assigned_Group>XXXX</ns0:Assigned_Group>
            <ns0:Assigned_Group_Shift_Name/>
            <ns0:Assigned_Support_Company>XXXX</ns0:Assigned_Support_Company>
            <ns0:Assigned_Support_Organization>XXXX</ns0:Assigned_Support_Organization>
            <ns0:Assignee/>
            <ns0:Categorization_Tier_1/>
            <ns0:Categorization_Tier_2/>
            <ns0:Categorization_Tier_3/>
            <ns0:City/>
            <ns0:Closure_Manufacturer/>
            <ns0:Closure_Product_Category_Tier1>XXXX</ns0:Closure_Product_Category_Tier1>
            <ns0:Closure_Product_Category_Tier2>XXXX</ns0:Closure_Product_Category_Tier2>
            <ns0:Closure_Product_Category_Tier3/>
            <ns0:Closure_Product_Model_Version/>
            <ns0:Closure_Product_Name/>
            <ns0:Company>XXXX</ns0:Company>
            <ns0:Contact_Company>XXXX</ns0:Contact_Company>
            <ns0:Contact_Sensitivity>Standard</ns0:Contact_Sensitivity>
            <ns0:Country/>
            <ns0:Department>XXXX</ns0:Department>
            <ns0:Summary>XXXX</ns0:Summary>
            <ns0:Notes/>
            <ns0:First_Name>XXXX</ns0:First_Name>
            <ns0:Impact>4-Minor/Localized</ns0:Impact>
            <ns0:Incident_Number>XXXX</ns0:Incident_Number>
            <ns0:Internet_E-mail>XXXX</ns0:Internet_E-mail>
            <ns0:Last_Name>XXXX</ns0:Last_Name>
            <ns0:Manufacturer/>
            <ns0:Organization>XXXX</ns0:Organization>
            <ns0:Phone_Number>XXXX</ns0:Phone_Number>
            <ns0:Priority>Low</ns0:Priority>
            <ns0:Priority_Weight>0</ns0:Priority_Weight>
            <ns0:Product_Categorization_Tier_1>XXXX</ns0:Product_Categorization_Tier_1>
            <ns0:Product_Categorization_Tier_2>XXXX</ns0:Product_Categorization_Tier_2>
            <ns0:Product_Categorization_Tier_3/>
            <ns0:Product_Model_Version/>
            <ns0:Product_Name/>
            <ns0:Region/>
            <ns0:Reported_Source xsi:nil="true"/>
            <ns0:Resolution/>
            <ns0:Resolution_Category/>
            <ns0:Resolution_Category_Tier_2/>
            <ns0:Resolution_Category_Tier_3/>
            <ns0:Service_Type>User Service Restoration</ns0:Service_Type>
            <ns0:Site>XXXX</ns0:Site>
            <ns0:Site_Group>XXXX</ns0:Site_Group>
            <ns0:Status>Cancelled</ns0:Status>
            <ns0:Status_Reason xsi:nil="true"/>
            <ns0:Urgency>4-Low</ns0:Urgency>
            <ns0:VIP>No</ns0:VIP>
            <ns0:ServiceCI/>
            <ns0:ServiceCI_ReconID/>
            <ns0:HPD_CI/>
            <ns0:HPD_CI_ReconID/>
            <ns0:HPD_CI_FormName/>
            <ns0:z1D_CI_FormName/>
            <ns0:Vendor_Ticket_Number xsi:nil="true"/>
            <ns0:Corporate_ID>XXXX</ns0:Corporate_ID>
            <ns0:Submitter>XXXX</ns0:Submitter>
            <ns0:Pending_Date xsi:nil="true"/>
         </ns0:getListValues>
      </ns0:HelpDesk_QueryList_ServiceResponse>
   </soapenv:Body>
</soapenv:Envelope>

回答by GPI

First, it seems that your error occurs while the SAAJ framework processes the response. So I would not dig on the creation of the request, that I would assume is fine, particularly since you make the case that it is the same that the SoapUI forged one. You could also check HTTP headers to make extra sure of that.

首先,您的错误似乎是在 SAAJ 框架处理响应时发生的。所以我不会深入研究请求的创建,我认为这很好,特别是因为您认为它与 SoapUI 伪造的请求相同。您还可以检查 HTTP 标头以确保这一点。

The important part of the stack trace is :

堆栈跟踪的重要部分是:

at com.sun.xml.internal.messaging.saaj.soap.SOAPPartImpl.getEnvelope(SOAPPartImpl.java:128)
at com.sun.xml.internal.messaging.saaj.soap.MessageImpl.getSOAPBody(MessageImpl.java:1351)

Which tells us that the SOAP framework could not process the response envelope. Assuming the response is indeed valid, this looks suspiscious.

这告诉我们 SOAP 框架无法处理响应信封。假设响应确实有效,这看起来很可疑。

Looking at your code, what I suspect this is a misuse of the SAAJ API :

查看您的代码,我怀疑这是对 SAAJ API 的滥用:

// Close connection
soapConnection.close();

if (isSuccessResponse(soapResponse)) {
  System.out.println("Success!");
} else {
  System.out.println("Fault!");
}

You close the connection before actually using the message. If the SAAJ implemetation is lazy (which I guess it is, it would make sense), the message is not immediatly parsed from the network Socket. By closing the connection beforeusing the response message, you actually shut the socket before it has been read, and the implementation consequently can not read the message.

在实际使用消息之前关闭连接。如果 SAAJ 实现是懒惰的(我猜是这样,这是有道理的),则不会立即从网络 Socket 解析消息。通过使用响应消息之前关闭连接,实际上在读取之前关闭了套接字,因此实现无法读取消息。

I would suggest delaying the closing of the connection to afteryou used the response object.

我建议使用响应对象延迟关闭连接。

The same argument can be made of this part of the code :

可以对这部分代码进行相同的论证:

 System.out.print("SOAP Response:");
 System.out.println();
 soapResponse.writeTo(System.out);

 // Close connection
 soapConnection.close();

By dumping the response to the console, you actually make the framework consume the socket (read the HTTP response). Once you, later, ask the framework to parse the response stream as an envelope, if it has not cached the contents of the stream, then this operation fails : there are no more bytes to parse.

通过将响应转储到控制台,您实际上使框架使用了套接字(读取 HTTP 响应)。稍后,一旦您要求框架将响应流解析为信封,如果它还没有缓存流的内容,则此操作将失败:没有更多字节要解析。

So in a nutshell : do not "touch" the connection or the repsonse object before the framework has a chance to actually parse the result. This is not obvious from a API design standpoint, but it's an understandable behavior.

所以简而言之:在框架有机会实际解析结果之前,不要“触摸”连接或响应对象。从 API 设计的角度来看,这并不明显,但这是一种可以理解的行为。

Some other leads : Others on stackoverflow have reported that their old versions of Xerces/Xalan were the culprit (those are XML parsers, the JDK has its own version of Xerces built in), so you might want to check this too : Java Spring WS org.springframework.ws.soap.saaj.SaajSoapEnvelopeException: Could not access envelopehttp://mmmsoftware.blogspot.fr/2009/06/xml-namespace-error-with-spring-ws.html

其他一些线索:stackoverflow 上的其他人报告说,他们的旧版本 Xerces/Xalan 是罪魁祸首(那些是 XML 解析器,JDK 内置了自己的 Xerces 版本),因此您可能也想检查一下: Java Spring WS org.springframework.ws.soap.saaj.SaajSoapEnvelopeException:无法访问信封http://mmmsoftware.blogspot.fr/2009/06/xml-namespace-error-with-spring-ws.html