19

We've build an application using Spring and deployed it with Tomcat. We have a working REST interface, however one of our clients only has a SOAP client.

My understanding is that a SOAP web service and a REST web service cannot coexist on the same port or application.

What are my options for accepting a SOAP request with as little development as possible. Should I accept a soap packet via the rest interface and parse the XML? Or can I setup a SOAP interface communicate with my REST interface and respond back?

I'm using Gradle as my build tool. It would be nice to have the solution as part of a single WAR file

Max
  • 639
  • 2
  • 6
  • 19
  • 2
    Would it be simpler to develop a REST client for that customer? – jaco0646 Dec 06 '13 at 02:31
  • Actually this is a good point, but I think their application is in 'on the verge of death - touch it as little as possible' mode – Max Dec 06 '13 at 02:41

4 Answers4

14

In my experience, you can mix SOAP and REST in the same application if you're very careful about XML namespaces for JAXB. However, I wouldn't recommend it since updating one means risking the other's stability. Here is what I recommend...

  1. Setup a multi-project build in gradle
  2. Create three projects, one for the business logic, one for the REST interface, and one for the SOAP interface
  3. Modify the REST/SOAP interface to use common business logic project
  4. Deploy as two separate WARs

Should I accept a soap packet via the rest interface and parse the XML?

SOAP is a protocol and not just a format so this probably won't work with most (any?) frameworks.

Or can I setup a SOAP interface communicate with my REST interface and respond back?

You probably could at the expense of performance and/or maintainability.

Andrew White
  • 52,720
  • 19
  • 113
  • 137
  • Thanks. I will give that a crack. So one WAR has REST plus business logic and the other has the SOAP interface? – Max Dec 06 '13 at 02:36
  • IMHO, both WAR files will use a third jar providing the business logic. (sorry, couldn't leave this unanswered :-) ) – huch Feb 01 '18 at 07:25
4

We have a project that has similar requirements. We still have to support SOAP and we're going forward with ReST.

There is no reason that the two will conflict. Since you're using spring, you can even have the same domain objects as a response that gets marshalled to XML and JSON as your preference.

What you have to do is create different URI for the two. e.g someService/** for the SOAP and some-rest for the ReST implementations. You can have a service layer to handle shared logic (mostly the code needed on the end point and the rest controller is to fetch the required data from the service layer and sending it to be marshalled)

Just add some entry to your web.xml file to indicate the rest path and the endpoint paths...

Amanuel Nega
  • 1,899
  • 1
  • 24
  • 42
  • I agree on this approach. I've found REST based Java Jersey project with JAXB support that could help with this problem: https://www.ibm.com/developerworks/library/wa-aj-tomcat/ – reg Sep 12 '17 at 08:41
0

It sounds like your web service is primarily REST (it's 2013) but you have to support soap for a limited case. I'd design your web service with rest primarily in mind, but perhaps use a separate mechanism to indicate to the server that the client requires soap support. If possible, have the soap client send an http request header or use modified URL that perhaps ends in .soap. In any case there's no reason why you can't support both protocols on the same app.

seand
  • 5,168
  • 1
  • 24
  • 37
0

You can do that by following this Steps:

 -Add annotation of both Rest and Soap on class implementation.
 -Creating interface to hold the method annotation for Soap.
 -Put Rest annotation on method in class implementation.
 -Configure "web.xml" file to add "servlet" for Rest implementation you use.  
 -Don't forget to create class extend Application like [ApplicationConfiguration.class].

1- Class Implementation

@javax.jws.WebService(endpointInterface = "com.test.ebpp.autopayment.tess.ejb.GService", targetNamespace = "http://ejb.test.autopayment.ebpp.tess.com/", serviceName = "ApplicationBusinessFacadeService", portName = "ApplicationBusinessFacadePort")
@Path(value = "/ApplicationBusinessFacadeService")
public class ApplicationBusinessFacadePortBindingImpl implements
    ApplicationBusinessFacade {
    @Override
    @POST
    @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
    @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
    public ProcessResponse process(Process request) {
        //type your code 
    }
}

2- Service Interface

@WebService(name = "ApplicationBusinessFacade", targetNamespace =   "http://ejb.gateway.ebpp.com/")
@XmlSeeAlso({
com.ebpp.gateway.ejb.ObjectFactory.class,
com.ebpp.ifxmessages.ObjectFactory.class
})
public interface ApplicationBusinessFacade {

@WebMethod
@WebResult(targetNamespace = "")
@RequestWrapper(localName = "process", targetNamespace = "http://ejb.gateway.ebpp.com/", className = "com.ebpp.gateway.ejb.Process")
@ResponseWrapper(localName = "processResponse", targetNamespace = "http://ejb.gateway.ebpp.com/", className = "com.ebpp.gateway.ejb.ProcessResponse")
public ProcessResponse process(
    @WebParam(name = "arg0", targetNamespace = "")
    Process arg0);
 }

3- web.xml

 <servlet>        
        <servlet-name>com.ebpp.core.rs.config.ApplicationConfiguration</servlet-name>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>com.ebpp.core.rs.config.ApplicationConfiguration</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
 </servlet>
Zero Code
  • 19
  • 1
  • 3
  • this code run for me and for any more info you can send me on ahmed.albhy2001@gmail.com and for web.xml try change url-pattern to /rest/* – Zero Code Mar 11 '18 at 10:50