javaspringsoapjax-ws

Multiple SOAP services at same URL (different version of the same)


I have a need to support multiple versions of SOAP endpoint with the same URL, is this possible? Soap classes have been generated from a third party wsdl.

In web.xml I have:

<servlet>
  <servlet-name>soap</servlet-name>
  <servlet-class>com.sun.xml.ws.transport.http.servlet.WSSpringServlet</servlet-class>
  <load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>soap</servlet-name>
  <url-pattern>/soap/*</url-pattern>
</servlet-mapping>

In my applicationContext.xml I have the following:

<wss:binding url="/soap/StuffService/">
    <wss:service>
        <ws:service bean="#stuffV1"/>
    </wss:service>
</wss:binding>

<bean id="stuffV1" class="package.soap.StuffSoapEndpointV1"/>

And I have a java class:

@WebService(
        portName = "BasicHttpBinding_IStuffService",
        serviceName = "StuffService",
        endpointInterface = "package.soap.stuff.IStuffService",
        targetNamespace = "http://stuff.example.org/Integration/Service/Outgoing/v1",
        wsdlLocation = "/WEB-INF/Integration.Service.Outgoing.v1.IStuff.wsdl")
@ApiOperation(value = "Stuff Service")
public class StuffSoapEndpointV1 implements IStuffService {

Is it possible to add a second version to the same url? Something in the lines of:

<wss:binding url="/soap/StuffService/">
    <wss:service>
        <ws:service bean="#stuffV1"/>
        <ws:service bean="#stuffV2"/>
    </wss:service>
</wss:binding>

<bean id="stuffV1" class="package.soap.StuffSoapEndpointV1"/>
<bean id="stuffV2" class="package.soap.StuffSoapEndpointV2"/>


@WebService(
        portName = "BasicHttpBinding_IStuffService",
        serviceName = "StuffService",
        endpointInterface = "package.soap.stuff.IStuffService",
        targetNamespace = "http://stuff.example.org/Integration/Service/Outgoing/v2",
        wsdlLocation = "/WEB-INF/Integration.Service.Outgoing.v2.IStuff.wsdl")
@ApiOperation(value = "Stuff Service")
public class StuffSoapEndpointV2 implements IStuffService {

That doesn't work. Multiple ws:service tags are not allowed, same for wss:service and wss:binding with same url. Also I think that portName and serviceName combo should be unique, but they need to be same as in the wsdl which doesn't come from us.


Solution

  • I created my own handler for soap calls that is similar to https://github.com/revinate/jaxws-spring/blob/master/jaxws-spring/src/main/java/com/sun/xml/ws/transport/http/servlet/WSSpringServlet.java with basic functionality. And it uses my own WSServletDelegate.

    <servlet>
      <servlet-name>soap</servlet-name>
      <servlet-class>my.application.soap.WSSpecialServlet</servlet-class>
      <load-on-startup>2</load-on-startup>
    </servlet>
    

    But I added the WSServletDelegate so it could read multiple configurations for a binding url, marked with double asterix.

    <wss:binding url="/soap/eventService/**">
        <wss:service>
            <ws:service bean="#eventBeanV1"/>
        </wss:service>
    </wss:binding>
    <wss:binding url="/soap/eventService/**">
        <wss:service>
            <ws:service bean="#eventBeanV2"/>
        </wss:service>
    </wss:binding>
    

    And when a request comes to those urls with double asterix WSServletDelegate compares incoming SOAPAction header to beans methods Action annotation value, and if they are the same then that bean should be used.