无法使Spring SOAP客户端工作:内容类型“text/xml; charset=utf-8”不是预期的类型“application/soap+xml; charset=utf-8”。

6

你好,我在使用 Spring-ws 尝试创建一个简单的 Soap 客户端。我在搜索过程中发现了这个错误消息,说我正在使用 Soap 1.1 版本,需要指定 Soap 1.2 版本。我已经尝试着去指定了,下面的代码是否正确呢?如果这不是问题的原因,有没有人能看出问题所在呢?

以下是堆栈跟踪信息:

org.springframework.ws.client.WebServiceTransportException: Cannot process the message because the content type 'text/xml; charset=utf-8' was not the expected type 'application/soap+xml; charset=utf-8'. [415]
    at org.springframework.ws.client.core.WebServiceTemplate.handleError(WebServiceTemplate.java:663)
    at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:587)
    at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:537)
    at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:492)
    at org.springframework.ws.client.core.WebServiceTemplate.sendSourceAndReceiveToResult(WebServiceTemplate.java:436)
    at com.jda.fileserver.FujiAuthenticationTest.testLogin(FujiAuthenticationTest.java:53)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

这是我的代码,感谢您的帮助:
public class AuthTest {
@Test
public void testLogin() throws Exception {
        StringBuffer loginXml = new StringBuffer();
        loginXml.append("<soapenv:Envelope xmlns:soapenv=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:ns=\"http://abc.com/xyz/2010/08\">");
        loginXml.append("  <soapenv:Header>");
        loginXml.append("    <ns:loginOperationDetails>");
        loginXml.append("    </ns:loginOperationDetails>");
        loginXml.append("  </soapenv:Header>");
        loginXml.append("  <soapenv:Body>");
        loginXml.append("    <ns:LogIn>");
        loginXml.append("      <ns:logInInfo>");
        loginXml.append("        <ns:CustomerAccountId>customer1</ns:CustomerAccountId>");
        loginXml.append("        <ns:Username>jsmith</ns:Username>");
        loginXml.append("        <ns:Password>abc123</ns:Password>");
        loginXml.append("      </ns:logInInfo>");
        loginXml.append("    </ns:LogIn>");
        loginXml.append("  </soapenv:Body>");
        loginXml.append("</soapenv:Envelope>");

        WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
        SaajSoapMessageFactory defaultMessageFactory = (SaajSoapMessageFactory) webServiceTemplate.getMessageFactory();
        defaultMessageFactory.setSoapVersion(SoapVersion.SOAP_12);
        webServiceTemplate.setMessageFactory(defaultMessageFactory); // probably not needed

        StreamSource source = new StreamSource(new StringReader(loginXml.toString()));
        StreamResult result = new StreamResult(System.out);
        String uri = "http://xyz.abcstage.com/xyz_1.0/membership.svc/ws";
        SoapActionCallback requestCallback = new SoapActionCallback("http://abc.com/xyz/2010/08/MembershipService/LogIn");
        try {
            webServiceTemplate.sendSourceAndReceiveToResult(uri, source, requestCallback, result);
        } 
        catch (SoapFaultException sfe) {
            throw new Exception("SoapFaultException", sfe);
        }
        catch (WebServiceTransportException wste) {
            throw new Exception("WebServiceTransportException", wste);
        }
    }
}

当您没有在MessageFactory上尝试设置SoapVersion时,是否也遇到了错误? - evandongen
是的。而且我刚刚连接了Wireshark,我的客户端明显发送了content-type: text/xml而不是application/soap+xml。 - Steve L
4个回答

4

好的,我解决了上述问题,但是又遇到了另一个问题。首先,这是我如何解决上述问题的。现在我不再在SaajSoapMessageFactory上设置SOAP版本,而是在包装的MessageFactory上设置它。现在我的请求中传出的Content-Type是application/soap+xml。

WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
MessageFactory msgFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
SaajSoapMessageFactory newSoapMessageFactory = new SaajSoapMessageFactory(msgFactory);
webServiceTemplate.setMessageFactory(newSoapMessageFactory);

下一个问题,现在我遇到了这个:
org.springframework.ws.soap.client.SoapFaultClientException: Unexpected fault in the service.
    at org.springframework.ws.soap.client.core.SoapFaultMessageResolver.resolveFault(SoapFaultMessageResolver.java:37)
    at org.springframework.ws.client.core.WebServiceTemplate.handleFault(WebServiceTemplate.java:774)
    at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:600)
    at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:537)
    at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:492)
    at org.springframework.ws.client.core.WebServiceTemplate.sendSourceAndReceiveToResult(WebServiceTemplate.java:436)

以下是响应中返回的信息:

500 Internal Server Error
The SOAP action specified on the message, '', does not match the HTTP SOAP Action, 'http://abc.com/xyz/2010/08/MembershipService/LogIn'.

我会尽力解决这个问题,但是我想更新一下任何正在阅读这篇文章的人,让他们停止研究之前的错误。我需要找出如何正确设置SOAP操作。


我准备关闭此请求,并开始一个全新的请求,标题能够反映当前的问题。 - Steve L
1
我在这里发起了一个新的问题:https://dev59.com/52Uq5IYBdhLWcg3wV_Ei - Steve L

2
请使用以下代码在Spring WebService模板的marshallSendAndReceive方法中更改头部内容类型为text/xml;charset=utf-8。
  WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
webServiceTemplate.marshalSendAndReceive(url, request, new WebServiceMessageCallback() {

                public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException {
                    SaajSoapMessage soapMessage = (SaajSoapMessage) message;
                    MimeHeaders headers = soapMessage.getSaajMessage().getMimeHeaders();
                    headers.addHeader(TransportConstants.HEADER_CONTENT_TYPE, "text/xml;charset=utf-8");

1
谢谢Abhishek。不幸的是,我不再在那个公司或软件开发领域工作了。但我很喜欢阅读你的答案。 - Steve L

0

使用setHeader,因为您可能想要替换现有标头的内容或在不存在时添加它。虽然Httpheaders应该是不区分大小写的,但使用addHeader会做到这一点。当调用addHeader()时,通过源代码进行调试,即使忽略大小写,您将看到它在其他标头之后插入新标头。 因此,在Java中,最终将得到

content-type:

Content-Type:

            public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException {
                SaajSoapMessage soapMessage = (SaajSoapMessage) message;
                MimeHeaders headers = soapMessage.getSaajMessage().getMimeHeaders();
                headers.setHeader(TransportConstants.HEADER_CONTENT_TYPE, "text/xml;charset=utf-8");

0

对于在SOAP标头中添加操作和to标签,以下代码对我来说运行良好。

public void doWithMessage(WebServiceMessage message) throws IOException {
    SaajSoapMessage soapMessage = (SaajSoapMessage) message;

    SoapEnvelope soapEnvelope = soapMessage.getEnvelope();
    SoapHeader soapHeader = soapEnvelope.getHeader();

    //Initialize QName for Action and To
    QName action = new QName("{uri}", "Action", "{actionname}");
    QName to = new QName("{uri}", "To", "{actionname}");

    soapHeader.addNamespaceDeclaration("{actionname}", "{uri}");

    SoapHeaderElement soapHeaderElementAction = soapHeader.addHeaderElement(action);
    SoapHeaderElement soapHeaderElementTo = soapHeader.addHeaderElement(to);

    soapHeaderElementAction.setText("{text inside the tags}");

    soapHeaderElementTo.setText("{text inside the tags}");

    soapMessage.setSoapAction("{add soap action uri}");

    soapMessage.writeTo(out);

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接