Spring WS+JAXB

Download projects

Here is sample Spring WS application that shows how to expose your bean method as WS service and handle XML marshaling using JAXB.

There are 4 major parts involved here.

1. Define your XML schemas. Unlike some other WS frameworks Spring WS starts from WSDL’s or XSD’s.

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns="http://equilibriums.com/sample-spring-ws"
targetNamespace="http://equilibriums.com/sample-spring-ws"
elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">

   <xs:element name="sampleRequest" type="sampleRequestType" />

        <xs:complexType name="sampleRequestType">
                <xs:sequence>
                        <xs:element name="request" type="xs:string" minOccurs="0" />
                </xs:sequence>
        </xs:complexType>

        <xs:element name="sampleResponse" type="sampleResponseType" />

        <xs:complexType name="sampleResponseType">
                <xs:sequence>
                        <xs:element name="response" type="xs:string" minOccurs="0" />
                </xs:sequence>
        </xs:complexType>

</xs:schema>

2. web.xml.

<servlet>
        <servlet-name>sample-spring-ws</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>sample-spring-ws</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

Please note, that according to Spring documentation, its better to use “MessageDispatcherServlet” but I found it too limiting. For example I could not use multiple “SoapMessageDispatcher”‘.

3. Boring Spring WebServices beans and JAXB marshaller.

<bean class="org.springframework.ws.transport.http.WsdlDefinitionHandlerAdapter">
        <property name="transformLocations" value="true" />
    </bean>

    <bean class="org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter">
                <property name="messageFactory">
                        <bean class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory" />
                </property>
        </bean>

        <bean id="payloadMapping" class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping" />

        <bean id="defaultHandlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>

        <bean id="baseWsdlDefinition" abstract="true" class="org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition">
                <property name="requestSuffix" value="Request" />
                <property name="responseSuffix" value="Response" />
        </bean>

        <bean id="sampleJaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
                <property name="classesToBeBound">
                        <list>
                                <value>com.equilibriums.samplespringws.SampleRequest</value>
                                <value>com.equilibriums.samplespringws.SampleResponse</value>
                        </list>
                </property>
                <property name="marshallerProperties">
                        <map>
                                <entry key="jaxb.formatted.output">
                                        <value type="java.lang.Boolean">true</value>
                                </entry>
                        </map>
                </property>
        </bean>
        <alias name="sampleJaxbMarshaller" alias="sampleJaxbUnmarshaller" />

        <bean id="sampleSoapMessageDispatcher" class="org.springframework.ws.soap.server.SoapMessageDispatcher">
                <property name="endpointAdapters">
                        <list>
                                <bean class="org.springframework.ws.server.endpoint.adapter.MarshallingMethodEndpointAdapter">
                                        <property name="marshaller" ref="sampleJaxbMarshaller" />
                                        <property name="unmarshaller" ref="sampleJaxbUnmarshaller" />
                                </bean>
                        </list>
                </property>
        </bean>
    <alias name="sampleSoapMessageDispatcher" alias="/sample-spring-ws"/>

        <bean name="sampleWsdl" parent="baseWsdlDefinition">
                <property name="schemaCollection">
                        <bean class="org.springframework.xml.xsd.commons.CommonsXsdSchemaCollection">
                                <property name="xsds">
                                        <list>
                                                <value>/xsd/sample.xsd</value>
                                        </list>
                                </property>
                                <property name="inline" value="true" />
                        </bean>
                </property>
                <property name="portTypeName" value="Sample" />
                <property name="locationUri" value="/sample-spring-ws" />
                <property name="targetNamespace" value="http://equilibriums.com/sample-spring-ws"/>
        </bean>
        <alias name="sampleWsdl" alias="/sample.wsdl"/>

        <bean id="sampleEndpoint" class="com.equilibriums.samplespringws.SampleEndpoint">
        </bean>

As mentioned above we can define multiple “SoapMessageDispatcher” that use different parsers (some times its cleaner to have multiple JAXB marshallers that are configured with POJOs for each WebService).

4. Your Endpoint. Spring will use your Endpoint PayloadRoot annotation to match WS request to appropriate method.

package com.equilibriums.samplespringws;

import org.springframework.ws.server.endpoint.annotation.Endpoint;
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;

@Endpoint
public class SampleEndpoint{

    @PayloadRoot(localPart = "sampleRequest", namespace = "http://equilibriums.com/sample-spring-ws")
    public SampleResponse processSampleRequest(SampleRequest request){
        SampleResponse result = new SampleResponse();
        result.setResponse( "Request was: " + request.getRequest() );
        return result;
    }
}

And finally you can access WSDL using “http://localhost:8080/sample.wsdl” (assuming its deployed under http://localhost:8080) and call WebService using soapUI standalone application or its Eclipse plugin.

1 comment to Spring WS+JAXB

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>