Spring-WS client not setting SOAPAction header

后端 未结 3 1181
迷失自我
迷失自我 2020-12-08 08:08

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

相关标签:
3条回答
  • 2020-12-08 08:55

    Another walk-around is to add an interceptor and set the soapAction within the handleRequest() method that inbound receives the MessageContext from which the SoapMessage can be derived;

    after that you can easily set the soapAction invoking the setSoapAction() method.

    here is the code of the interceptor class:

    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..
    }
    

    and of course add the interceptor to the WebTemplate:

    WebServiceTemplate webServiceTemplate = new WebServiceTemplate(marshaller);
    ClientInterceptor[] interceptors = new ClientInterceptor[]{new SecurityInterceptor(parameters)};
    webServiceTemplate.setInterceptors();
    webServiceTemplate.marshalSendAndReceive(uriWebService, request)
    
    0 讨论(0)
  • 2020-12-08 08:57

    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;
    }
    
    0 讨论(0)
  • 2020-12-08 09:06

    A complete answer goes as follow.

    While you are using WebServiceTemplate as a class to communicate with the Webservice, I do not understand why but it does not properly fill the HTTP Header.

    Some WSDL have a part saying:

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

    And the WebServiceTemplate ignores this part. The above error means that your soapAction parameter in the header is empty. And it should be not. Check with Wireshark. I did - using some Chrome Soap client and Spring. The second one has an invalid header.


    To fix this you need to follow Section 6.2.4 in here: http://docs.spring.io/spring-ws/sites/2.0/reference/html/client.html

    What it says is basically add the header part on your own, with WebServiceMessageCallback interface. You can read more in the reference.

    Basically it ends up like this:

     webServiceTemplate.marshalSendAndReceive(o, new WebServiceMessageCallback() {
    
        public void doWithMessage(WebServiceMessage message) {
            ((SoapMessage)message).setSoapAction("http://tempuri.org/Action");
        }
    });
    

    Where you can set up properly the header value. Worked for me too. Whole day of reading.

    0 讨论(0)
提交回复
热议问题