【问题标题】:SOAP service call fails when SOAPMessage.writeTo is not called未调用 SOAPMessage.writeTo 时 SOAP 服务调用失败
【发布时间】:2015-01-09 16:36:11
【问题描述】:

我正在尝试调用 SOAP 服务,但在我构建了 SOAPMessage 之后,如果我调用 SOAPMessage.writeTo(out),服务调用会成功完成,但当我忽略它时它会失败。

我很确定在发送请求之前调用writeTo() 不是强制性步骤,我做错了。

有什么想法吗?

这里是详细信息

我的客户

public class Test {
    public static void main(String args[]) throws Exception {
        // Create SOAP Connection
        SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
        SOAPConnection soapConnection = soapConnectionFactory.createConnection();

        // Send SOAP Message to SOAP Server
        String url = "https://mydomain.com/webservices/gateway/IdMgt/CorporateDirectoryLookupPort";
        SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(), url);

        // print SOAP Response
        soapResponse.writeTo(System.out);
        soapConnection.close();
    }

    private static SOAPMessage createSOAPRequest() throws Exception {

        String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
                + "<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:Header>"
                + "<ns1:Security soapenv:mustUnderstand=\"0\" xmlns:ns1=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\">"
                + "<ns1:UsernameToken>"
                + "<ns1:Username></ns1:Username>"
                + "<ns1:Password></ns1:Password>"
                + "</ns1:UsernameToken>"
                + "</ns1:Security>"
                + "</soapenv:Header>"
                + "<soapenv:Body>"
                + "<GetAccountDetailsRequest2 xmlns=\"http://anotherdomain/schema/tCorporateDirectoryLookupV1\">"
                + "<MessageHeader xmlns=\"\"/><UserID xmlns=\"\"></UserID>"
                + "<AccountID xmlns=\"\">ServiceDeskAPIprd</AccountID>"
                + "</GetAccountDetailsRequest2></soapenv:Body>"
                + "</soapenv:Envelope>";

        InputStream is = new ByteArrayInputStream(xml.getBytes());
        SOAPMessage soapMessage = MessageFactory.newInstance().createMessage(
                null, is);

        /* Print the request message */
        soapMessage.writeTo(System.out);
        System.out.println();
        return soapMessage;
    }
}

createSOAPRequest 中的soapMessage.writeTo(System.out)NOT 注释掉时,我得到一个有效响应,但是当它被注释掉时,我得到

<?xml version="1.0" encoding="utf-8"?>
<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>
  <soapenv:Fault>
   <faultcode xmlns:ns1="http://xml.apache.org/axis/">ns1:Client.NoSOAPAction</faultcode>
   <faultstring>no SOAPAction header!</faultstring>
   <detail>
    <ns2:hostname xmlns:ns2="http://xml.apache.org/axis/">lxvirt150</ns2:hostname>
   </detail>
  </soapenv:Fault>
 </soapenv:Body>
</soapenv:Envelope>

【问题讨论】:

  • 我遇到了同样的问题。我注意到 SoapMessage 的“messageByteCount”字段在调用 writeTo 方法后被更新(在我的例子中是从 0 到 524)。我还注意到在 writeTo 方法的执行过程中调用了 saveMessage 方法,所以我尝试了而不是调用 writeTo(在调用 MessageFactory 之后),但没有这样做。你想清楚了吗?

标签: java web-services soap axis


【解决方案1】:

通过查看 writeTo 方法的实现,我发现他们在其末尾设置了“SOAPAction”标头:

if (isCorrectSoapVersion(4)) {
        String[] soapAction = this.headers.getHeader("SOAPAction");

        if ((soapAction == null) || (soapAction.length == 0)) {
            this.headers.setHeader("SOAPAction", "\"\"");
    }
}

因此,如果您想避免调用 writeTo 方法,实际上可以在创建 SOAPMessage 后自己设置标头:

SOAPMessage soapMessage = MessageFactory.newInstance().createMessage(
            null, is);
soapMessage.getMimeHeaders().addHeader("SOAPAction", "\"\"");

这对我有用。希望对您有所帮助!

皮埃尔

【讨论】:

    【解决方案2】:

    我遇到了同样的问题,但发现 saveChanges() 方法解决了它。来自 java 文档:

    Updates this SOAPMessage object with all the changes that
    have been made to it. This method is called automatically when
    SOAPMessage writeTo(OutputStream) is called. However, if
    changes are made to a message that was received or to one that has
    already been sent, the method saveChanges needs to be
    called explicitly in order to save the changes. The method saveChanges also generates any changes that can be read back (for example, a MessageId in profiles that support a message id). All MIME headers in a message that is created for sending purposes are guaranteed to have valid values only after saveChanges has been called.
    In addition, this method marks the point at which the data from all
    constituent AttachmentPart objects are pulled into the
    message.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-13
      • 1970-01-01
      相关资源
      最近更新 更多