Search code examples
javaintegration-testingspring-ws

How do I test a Spring-WS webservice that Requires soapHeaders?


I have a spring-ws (2.0.2) service I have implemented that requires some custom elements in the soap header. I am trying to use Spring's MockWebServiceClient to generate a valid request to test the dispatcher, marshallers, etc.

The problem I am getting is that the MockWebSerivce only seems to support the Soap Body (the payload).

How can I access the soap request being generated to get the right headers into it?

If there is a better library for doing this other than Spring's MockWebServiceClient, that would be fine too.

Related Links: http://forum.springsource.org/showthread.php?101708-MockWebServiceClient-amp-WS-Security
Add SoapHeader to org.springframework.ws.WebServiceMessage


Solution

  • I had the similar problem when I wanted to test spring web service with Security, I ended up using the Spring Interceptors to modify the header before they reach end point, I enabled the interceptors only for testing.

    Create an interceptor, I implemented the SmartEndpointInterceptor, You can use the other interceptors if you choose

    public class ModifySoapHeaderInterceptor implements
        SmartEndpointInterceptor 
    {
      //WSConstants.WSSE_NS;
       private static final String DEFAULT_SECURITY_URL = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
        private static final String SECURITY_TAG = "Security";
        private static final String SECURITY_PREFIX = "wsse";
        private static final String USER_NAME_TOKEN = "UsernameToken";
    
        @Override
    public boolean handleRequest(MessageContext messageContext, Object endpoint)
            throws Exception 
    {
          SaajSoapMessage saajSoapMessage(SaajSoapMessage)messageContext.getRequest());
          SOAPHeader soapHeader = saajSoapMessage.getSaajMessage().getSOAPPart()
                .getEnvelope().getHeader();
    
           //you can modify header's as you choose
           Name headerElement = saajSoapMessage.getSaajMessage().getSOAPPart()
                .getEnvelope()
                .createName(SECURITY_TAG, SECURITY_PREFIX, DEFAULT_SECURITY_URL);
           SOAPHeaderElement soapHeaderElement = soapHeader
                .addHeaderElement(headerElement);
        SOAPElement usernameToken = soapHeaderElement.addChildElement(
                USER_NAME_TOKEN, SECURITY_PREFIX);
    
        SOAPElement userNameElement = usernameToken.addChildElement("Username",
                SECURITY_PREFIX);
        userNameElement.addTextNode("userid");//you can inject via spring
    
        SOAPElement passwordElement = usernameToken.addChildElement("Password",
                SECURITY_PREFIX);
        passwordElement.addTextNode("password");
           return true;
        }
    }
    

    Configure this interceptor in spring context

      <sws:interceptors>
         <bean class="prasanna.ws.security.wss4j.ModifySoapHeaderInterceptor"/>
      </sws:interceptors>
    

    This will add the necessary security headers to the message before it reaches the end point, You can still use MockWebServiceClient to test your web service.