A very simple example of using Spring Web Services 1.5.x with JAXB for marshalling and unmarshalling requests. A JAXB plugin for Maven is used to generate the JAXB beans from and XSD and the XSD is reused to generate a WSDL. The response from the server sends a person list, but could easily be modified to retrieve person based on an ID.
The MessageDispatcherServlet needs to be defined and URL patterns it will handle.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<servlet>
<servlet-name>spring-ws</servlet-name>
<servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>spring-ws</servlet-name>
<url-pattern>/services</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>spring-ws</servlet-name>
<url-pattern>*.wsdl</url-pattern>
</servlet-mapping>
</web-app>
The PersonEndpoint is defined as a bean and will automatically be registered with Spring Web Services since the class
is identified as an endpoint by the @Endpoint annotation. This configuration uses the person.xsd that was used to generated
the JAXB beans to generate the WSDL. The locationUri matches the host and port the webapp is bound to including it's context namespace ('ws'),
and 'services' matches the URL pattern specified in the web.xml.
The JAXB marshaller/unmarshaller is configured using Spring OXM and also set on the MarshallingMethodEndpointAdapter bean.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="org.springbyexample.ws.service.PersonEndpoint"/>
<bean id="person" class="org.springframework.ws.wsdl.wsdl11.DynamicWsdl11Definition">
<property name="builder">
<bean class="org.springframework.ws.wsdl.wsdl11.builder.XsdBasedSoap11Wsdl4jDefinitionBuilder">
<property name="schema" value="classpath:/person.xsd"/>
<property name="portTypeName" value="Person"/>
<property name="locationUri" value="http://localhost:8080/ws/services"/>
<property name="targetNamespace" value="http://www.springbyexample.org/person/schema/beans"/>
</bean>
</property>
</bean>
<bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping">
<description>An endpoint mapping strategy that looks for @Endpoint and @PayloadRoot annotations.</description>
</bean>
<bean class="org.springframework.ws.server.endpoint.adapter.MarshallingMethodEndpointAdapter">
<description>Enables the MessageDispatchServlet to invoke methods requiring OXM marshalling.</description>
<constructor-arg ref="marshaller"/>
</bean>
<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="contextPath" value="org.springbyexample.person.schema.beans"/>
</bean>
</beans>
A very simple XSD defining an element to indicate an incoming request to get all persons (name element isn't used) and a person response element that contains a list of person elements.
<xsd:schema xmlns="http://www.springbyexample.org/person/schema/beans"
targetNamespace="http://www.springbyexample.org/person/schema/beans"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="get-persons-request">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="name" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="person-response">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="person" type="person"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="person">
<xsd:sequence>
<xsd:element name="id" type="xsd:int" />
<xsd:element name="first-name" type="xsd:string" />
<xsd:element name="last-name" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
Example 1. MarshallingPersonService
Interface for getting persons using the JAXB generated beans ('get-persons-request' element --> GetPersonsRequst? , 'person-response' element --> PersonResponse? ). It also has constants for the namespace (matches XSD) and a request constant.
public interface MarshallingPersonService {
public final static String NAMESPACE = "http://www.springbyexample.org/person/schema/beans";
public final static String GET_PERSONS_REQUEST = "get-persons-request";
/**
* Gets person list.
*/
public PersonResponse getPersons(GetPersonsRequest request);
}
Example 2. PersonEndpoint
It is indicated as an endpoint by the @Endpoint annotation and implements MarshallingPersonService.
The getPersons method is indicated to handle a specific namespace and incoming request element.
The endpoint just prepares a static response, but this could very easily have a DAO injected into it and information retrieved from a database that is then mapped into the JAXB beans.
@Endpoint
public class PersonEndpoint implements MarshallingPersonService {
/**
* Gets person list.
*/
@PayloadRoot(localPart=GET_PERSONS_REQUEST, namespace=NAMESPACE)
public PersonResponse getPersons(GetPersonsRequest request) {
PersonResponse response = new PersonResponse();
Person person = new Person();
person.setId(1);
person.setFirstName("Joe");
person.setLastName("Smith");
Person person2 = new Person();
person2.setId(2);
person2.setFirstName("John");
person2.setLastName("Jackson");
response.getPerson().add(person);
response.getPerson().add(person2);
return response;
}
}