Java 未调用SOAPMessage.writeTo时,SOAP服务调用失败

Java 未调用SOAPMessage.writeTo时,SOAP服务调用失败,java,web-services,soap,axis,Java,Web Services,Soap,Axis,我试图调用一个SOAP服务,但是在我构建了SOAPMessage之后,如果我调用SOAPMessage.writeTo(out)服务调用成功完成,但如果我忽略它,它将失败 我很确定,在发送请求之前,调用writeTo()不是必须的步骤,我做错了什么 有什么想法吗 详情如下 我的客户 public class Test { public static void main(String args[]) throws Exception { // Create SOAP Con

我试图调用一个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;
    }
}

通过查看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", "\"\"");
这对我很管用。我希望这有帮助


Pierre

我也遇到过同样的问题,但发现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.

我遇到了同样的问题。我注意到SoapMessage的字段“messageByteCount”在调用writeTo方法后被更新(在我的例子中是从0到524)。我还注意到saveMessage方法是在writeTo方法的执行过程中调用的,因此我尝试了调用writeTo(就在调用MessageFactory之后),但没有这样做。你明白了吗?
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.