本文介绍了Spring-WS 客户端未设置 SOAPAction 标头的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在发送 SOAP 请求,但服务器抱怨 SOAPAction 标头为空.我认为我设置正确,但显然我不是.Wireshark 显示未设置.

I'm sending a SOAP request and the server is complaining that the SOAPAction header is empty. I think I'm setting it right, but obviously I'm not. Wireshark shows it's not set.

@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://example.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>JDoe</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();
    MessageFactory msgFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
    SaajSoapMessageFactory newSoapMessageFactory = new SaajSoapMessageFactory(msgFactory);
    webServiceTemplate.setMessageFactory(newSoapMessageFactory);

    String uri = "http://xyz.example.com/xyz_1.0/membership.svc/ws";
    webServiceTemplate.setDefaultUri(uri);

    StreamSource source = new StreamSource(new StringReader(loginXml.toString()));
    StreamResult result = new StreamResult(System.out);

    boolean resultReturned = false;
    try {
        resultReturned = webServiceTemplate.sendSourceAndReceiveToResult(source,
            new SoapActionCallback("http://example.com/xyz/2010/08/MembershipService/LogIn"),
            result);
    }
    catch (SoapFaultClientException sfe) {
        logger.error("SoapFaultClientException resultReturned: " + resultReturned, sfe);
        fail();
    }
}

我从服务器返回的错误说:

The error I'm getting back from the server says:

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

推荐答案

我解决了这个问题,但从未发布过答案.这是我最终得到的结果:

I worked this out but never posted the answer. Here's what I ended up with that works well:

public WebServiceTemplate getWebServiceTemplate() throws SOAPException {
  if (webServiceTemplate == null) {
    final MessageFactory msgFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
    final SaajSoapMessageFactory newSoapMessageFactory = new SaajSoapMessageFactory(msgFactory);
    webServiceTemplate = new WebServiceTemplate(newSoapMessageFactory);
  }

  return webServiceTemplate;
}

public Object sendReceive(Object requestObject, ArrayList<String> classesToMarshall, final String action)
        throws ClassNotFoundException, SoapFaultException, SoapFaultClientException, WebServiceTransportException,
        IllegalStateException, SOAPException {

  final WebServiceTemplate wst = getWebServiceTemplate();

    final SoapMarshallUtil smu = getSoapMarshallUtil();
    smu.configureMarshaller(wst, classesToMarshall);

    // soap 1.2
    SoapActionCallback requestCallback = new SoapActionCallback(action) {
        public void doWithMessage(WebServiceMessage message) {
            SaajSoapMessage soapMessage = (SaajSoapMessage) message;
            SoapHeader soapHeader = soapMessage.getSoapHeader();

            QName wsaToQName = new QName("http://www.w3.org/2005/08/addressing", "To", "wsa");
            SoapHeaderElement wsaTo =  soapHeader.addHeaderElement(wsaToQName);
            wsaTo.setText(uri);

            QName wsaActionQName = new QName("http://www.w3.org/2005/08/addressing", "Action", "wsa");
            SoapHeaderElement wsaAction =  soapHeader.addHeaderElement(wsaActionQName);
            wsaAction.setText(action);
        }
    };

    Object responseObject = wst.marshalSendAndReceive(this.uri, requestObject, requestCallback);
    return responseObject;
}

这篇关于Spring-WS 客户端未设置 SOAPAction 标头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-10 09:06