SpringWS客户端未设置SOAPAction头

SpringWS客户端未设置SOAPAction头,soap,soap-client,spring-ws,Soap,Soap Client,Spring Ws,我正在发送一个SOAP请求,而服务器正在抱怨SOAPAction头是空的。我想我把它设置好了,但显然我没有。Wireshark显示它没有设置 @Test public void testLogin() throws Exception { StringBuffer loginXml = new StringBuffer(); loginXml.append("<soapenv:Envelope xmlns:soapenv=\"http://www.w3.org/2003/0

我正在发送一个SOAP请求,而服务器正在抱怨SOAPAction头是空的。我想我把它设置好了,但显然我没有。Wireshark显示它没有设置

@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();
    }
}

我算出来了,但从未公布过答案。下面是我最后得到的效果很好的东西:

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;
}
公共WebServiceTemplate getWebServiceTemplate()引发SOAPException{
如果(webServiceTemplate==null){
final MessageFactory msgFactory=MessageFactory.newInstance(SOAPConstants.SOAP\u 1\u 2\u协议);
最终SaajSoapMessageFactory newSoapMessageFactory=新的SaajSoapMessageFactory(MSGFFactory);
webServiceTemplate=新的webServiceTemplate(newSoapMessageFactory);
}   
返回webServiceTemplate;
}
公共对象sendReceive(对象请求对象、ArrayList类、最终字符串操作)
抛出ClassNotFoundException、SoapFaultException、SoapFaultClientException、WebServiceTransportException、,
非法状态异常,SOAPException{
最终WebServiceTemplate wst=getWebServiceTemplate();
最终soapmarshalllutil smu=getsoapmarshalllutil();
smu.configureMarshaller(wst,classesToMarshall);
//肥皂1.2
SoapActionCallback requestCallback=新的SoapActionCallback(操作){
公共无效doWithMessage(WebServiceMessage消息){
SaajSoapMessage soapMessage=(SaajSoapMessage)消息;
SoapHeader SoapHeader=soapMessage.getSoapHeader();
QName wsaToQName=新的QName(“http://www.w3.org/2005/08/addressing“,”至“,”wsa”);
SoapHeaderElement wsaTo=soapHeader.addHeaderElement(wsaToQName);
wsaTo.setText(uri);
QName wsaActionQName=新的QName(“http://www.w3.org/2005/08/addressing“行动”、“wsa”);
SoapHeaderElement WSAAAction=soapHeader.addHeaderElement(WSAAActionQName);
wsaaaction.setText(操作);
}
};
Object responseObject=wst.marshalSendAndReceive(this.uri,requestObject,requestCallback);
返回响应对象;
}
完整答案如下所示。 当您使用
WebServiceTemplate
作为一个类与Webservice通信时,我不理解为什么,但它没有正确地填充HTTP头

有些WSDL的一部分是这样说的:

<soap:operation
            soapAction="SOMELINK"
            style="document" />

您可以在其中正确设置标题值。也为我工作。一整天的阅读。

另一个方法是添加一个拦截器,并在
HandlerRequest()
方法中设置soapAction,inbound接收可以从中派生
SoapMessage
MessageContext

之后,您可以通过调用
setSoapAction()
方法轻松设置soapAction

以下是拦截器类的代码:

public class SecurityInterceptor implements ClientInterceptor {

    @Override
    public boolean handleRequest(MessageContext messageContext) throws WebServiceClientException {

        SoapMessage soapMessage = (SoapMessage) messageContext.getRequest();
        soapMessage.setSoapAction("mySoapAction");    

        return true;
    }

    //TODO:: other methods and constructor..
}
当然,还要将拦截器添加到
WebTemplate

WebServiceTemplate webServiceTemplate = new WebServiceTemplate(marshaller);
ClientInterceptor[] interceptors = new ClientInterceptor[]{new SecurityInterceptor(parameters)};
webServiceTemplate.setInterceptors();
webServiceTemplate.marshalSendAndReceive(uriWebService, request)

作品很有魅力,谢谢你帮了我不少忙!我想知道这是否能自动完成。添加这个硬编码值对我来说很有用,但是用这样的东西把我的代码弄得乱七八糟是不太好的。@Michal您总是可以通过使用属性文件使它更参数化。请注意,由于SOAPAction标头已被弃用,此解决方案不适用于SOAP1.2。实际上,由于SOAPAction未被自动填充,因此SOAP1.1的正确性工作是不可取的。
public class SecurityInterceptor implements ClientInterceptor {

    @Override
    public boolean handleRequest(MessageContext messageContext) throws WebServiceClientException {

        SoapMessage soapMessage = (SoapMessage) messageContext.getRequest();
        soapMessage.setSoapAction("mySoapAction");    

        return true;
    }

    //TODO:: other methods and constructor..
}
WebServiceTemplate webServiceTemplate = new WebServiceTemplate(marshaller);
ClientInterceptor[] interceptors = new ClientInterceptor[]{new SecurityInterceptor(parameters)};
webServiceTemplate.setInterceptors();
webServiceTemplate.marshalSendAndReceive(uriWebService, request)