Search code examples
javaweb-servicesrestsoapspring-ws

Convert SOAP to a virtual Restful service?


Is there a way to use my SOAP web service(spring-ws, java) as a XML based RESTful service virtually?

I don't want to re-write whole my SOAP web service into RESTful from scratch in java, but I need to access it through iphone using REST, which they already have easy native support.

XMLGateway, Proxys..? or some extra java code? since my SOAP request and response is simply an XML file why can't I modify it to be used by a REST service?

Or without changing changing any logic and xml parsing in my application is that easy to add jax-rs annotations and create a rest request xml?

my config spring file is like this:

<bean id="webServicePluginDescriptor"
    class="com.mysite.ws.configuration.MyWebservicePluginDescriptor" />

<bean id="payloadMapping"
    class="org.springframework.ws.server.endpoint.mapping.PayloadRootQNameEndpointMapping">
    <property name="defaultEndpoint" ref="inferenceEndPoint" />
    <property name="interceptors">
        <list>
            <ref local="validatingInterceptor" />
            <ref local="payLoadInterceptor" />
        </list>
    </property>
</bean>

<bean id="payLoadInterceptor"
    class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor" />

<bean id="validatingInterceptor"
    class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor">
    <property name="schema"
        value="classpath:/wsdl/Request.xsd" />
    <property name="validateRequest" value="true" />
    <property name="validateResponse" value="false" />
</bean>

<bean id="PropertyResource" class="com.mysite.ws.im.PropertyResource">
    <property name="resource"
        value="/WEB-INF/client-specific/InferenceMachine.properties" />
</bean>

<bean id="inferenceEndPoint" class="com.mysite.ws.web.InferenceEndPoint">
    <property name="messageWebService" ref="messageWebService" />
</bean>
<bean id="messageWebService" class="com.mysite.ws.service.MessageWebService"
    scope="request">
    <aop:scoped-proxy />
    <property name="inferenceService" ref="inferenceService" />
</bean>

<bean id="Request" class="org.springframework.xml.xsd.SimpleXsdSchema">
    <property name="xsd" value="classpath:/wsdl/Request.xsd" />
</bean>

<bean id="Response" class="org.springframework.xml.xsd.SimpleXsdSchema">
    <property name="xsd" value="classpath:/wsdl/Response.xsd" />
</bean>

<bean id="Error" class="org.springframework.xml.xsd.SimpleXsdSchema">
    <property name="xsd" value="classpath:/wsdl/Error.xsd" />
</bean>

<bean id="mwsid"
    class="org.springframework.ws.wsdl.wsdl11.SimpleWsdl11Definition">
    <constructor-arg value="classpath:/wsdl/mtchwsdl.wsdl" />
</bean>

<bean id="inferenceService" class="com.mysite.ws.im.InferenceService"
    scope="request">
    <aop:scoped-proxy />
    <property name="webServiceConfiguration" ref="wsPlayerConfiguration" />

    <property name="properties">
        <bean class="com.mysite.ws.im.PropertyResource">
            <property name="resource"
                value="/WEB-INF/client-specific/InferenceMachine.properties" />
        </bean>
    </property>
</bean>

<!-- ~~~~~~~ Application beans ~~~~~~~ -->
<bean id="wsPlayerConfiguration"
    class="com.mysite.ws.configuration.WebServiceConfiguration"
    scope="request">
    <aop:scoped-proxy />
    <property name="playerConfiguration" ref="playerConfiguration"></property>
    <property name="configurationSetup" ref="configurationSetup"></property>
</bean>

and this is my endpoint class:

/**
 * The EndPoint of the Web Service Application. This class gets the raw
 * SOAP-body message from the Spring Payload Dispatcher and sends the message to
 * the @see MessageService class. After it has gotten the response XML message
 * it returns this back to the Spring Payload Dispatcher.
 */
public class InferenceEndPoint extends AbstractJDomPayloadEndpoint {

    private MessageWebService messageWebService;
    public InferenceEndPoint() {
    }

    @Override
    protected Element invokeInternal(Element inferenceRequest) throws Exception {
        Element ret = messageWebService.handleRequest(inferenceRequest);
        return ret;
    }

    /**
     * @param messageWebService
     */
    public void setMessageWebService(MessageWebService messageWebService) {
        this.messageWebService = messageWebService;
    }
}

any ideas?


Solution

  • There's nothing stopping you from send POST filled with XML to get results filled with XML back.

    The simplest thing to do is somehow capture the SOAP requests going back and forth, and simply turn the request in to a template with the blanks being your parameters, and then using XPath on the resulting XML to pull your results out.

    The only nit being you might need SOAPAction header in your POST, but likely not.

    It's really no big deal. If you have dozens of methods, it's more of a pain. Also, if you're using any of the encryption parts of SOAP, then it's more of a pain. But if just a few, in the end it's just XML, and a bulk of that XML is boilerplate, so looked at that way, it's pretty straightforward.

    Addenda:

    If you have back end logic that you want to front with a more HTTP friendly service, then JAX-RS can to that quite easily, but it would require coding on the server end.

    If you have an existing SOAP web service that you wish to use, then forget the whole SOAP part of the equation, and simply treat it as an HTTP web service that uses XML payloads. It's still SOAP, but you're not using any SOAP tooling on the client side. You're simply assembling XML payloads on the client requests (from templates would be easiest, IMHO), and consuming XML payloads as a result, and trading these over HTTP.

    Depending on how many different methods on the existing web service you intend to call gives you an idea of the scope of the work involved. It's simple work (once you can view the payloads easily), but it's still work. If you only have a few methods, especially if the interface is stable and not changing, it's far easier to just work with the raw XML than learn and fight some new unfamiliar framework.