Monday, 18 February 2013

Spring SOAP Server


STEP 1

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "ServiceRequest", namespace = EccountServiceEndpoint.NAMESPACE_URI)
@XmlAccessorType(XmlAccessType.FIELD)
public class ServiceRequest implements Serializable {

private static final long serialVersionUID = 1L;

public static final String NAMESPACE = "http://www.eccount.com/eccount/ews/schemas";

private String username;

private String password;

private String serviceCode;

private List<EccountMapEntry> requestFields;
}


STEP 2

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "EccountMapEntry", namespace = EccountServiceEndpoint.NAMESPACE_URI)
@XmlAccessorType(XmlAccessType.FIELD)
public class EccountMapEntry implements Serializable {

private static final long serialVersionUID = -1068419604611623560L;

public static final String NAMESPACE = "http://www.eccount.com/eccount/ews/schemas";

private String key;
private String value;
}


STEP 3

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "ServiceResponse", namespace = EccountServiceEndpoint.NAMESPACE_URI)
@XmlAccessorType(XmlAccessType.FIELD)
public class ServiceResponse implements Serializable {
private static final long serialVersionUID = 1L;

public static final String NAMESPACE = "http://www.eccount.com/eccount/ews/schemas";

private String serviceInfoId;

private String responseCode;

private String responseMessage;

private EccountServiceStatus status;

private List<EccountMapEntry> responseFields;
}


STEP 4

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "EccountServiceStatus", namespace = EccountServiceEndpoint.NAMESPACE_URI)
@XmlAccessorType(XmlAccessType.FIELD)
public enum EccountServiceStatus {
SUCCESS, FAILURE
}



STEP 5


<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.eccount.com/eccount/ews/schemas"
targetNamespace="http://www.eccount.com/eccount/ews/schemas">
<element name="ServiceRequest">
<complexType>
<sequence>
<element name="username" type="string"></element>
<element name="password" type="string"></element>
<element name="serviceCode" type="string"></element>
<element name="originatingUniqueId" type="string"></element>
<element name="requestFields" type="tns:EccountMapEntry" minOccurs="0" maxOccurs="unbounded"></element>
</sequence>
</complexType>
</element>
<element name="ServiceResponse">
<complexType>
<sequence>
<element name="serviceInfoId" type="string" minOccurs="0"></element>
<element name="status" type="tns:EccountServiceStatus"></element>
<element name="responseCode" type="string"></element>
<element name="responseMessage" type="string"></element>
<element name="responseFields" type="tns:EccountMapEntry" minOccurs="0" maxOccurs="unbounded"></element>
</sequence>
</complexType>
</element>

<complexType name="EccountMapEntry">
<sequence>
<element name="key" type="string" />
<element name="value" type="string" />
</sequence>
</complexType>

<simpleType name="EccountServiceStatus">
<restriction base="string">
<enumeration value="SUCCESS" />
<enumeration value="FAILURE" />
</restriction>
</simpleType>

</schema>



STEP 6  implementing the @Endpoint
Implement Endpoints to handle incoming XML messages. 
An @Endpoint is typically created by annotating a class with the @Endpoint annotation.

The @PayloadRoot annotation tells Spring-WS that the handleServiceRequest() method is suitable for handling XML messages.

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

@Endpoint
public class EccountServiceEndpoint {

public static final String NAMESPACE_URI = "http://www.eccount.com/eccount/ews/schemas";

private final IWsRequestProcessingApi wsRequestProcessingApi;

public EccountServiceEndpoint(IWsRequestProcessingApi wsRequestProcessingApi) {
this.wsRequestProcessingApi = wsRequestProcessingApi;
}

@PayloadRoot(namespace = NAMESPACE_URI, localPart = "ServiceRequest")
public @ResponsePayload
ServiceInfoResponse handleServiceRequest(@RequestPayload ServiceRequest request) {

try {
return wsRequestProcessingApi.processServiceInfo(request);
} catch (Exception exception) {
ServiceResponse response = new ServiceResponse();
//set response message
return response;
}
}
}


STEP 7 configure ws-context.xml and publishing the WSDL
configure the above classes in ws-context.xml Spring XML configuration file.


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:sws="http://www.springframework.org/schema/web-services"
xmlns:oxm="http://www.springframework.org/schema/oxm" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-2.0.xsd
  http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd
  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<sws:annotation-driven />

<sws:dynamic-wsdl id="eccountservice"
portTypeName="EccountService" locationUri="/ews/eccountservice"
targetNamespace="http://www.eccount.com/eccount/ews/schemas">
<sws:xsd location="classpath:/WEB-INF/xsds/ews.xsd" />
</sws:dynamic-wsdl>

<oxm:jaxb2-marshaller id="marshaller">
<oxm:class-to-be-bound
name=" com.zazzercode.eccount.server.ws.schemas.ServiceRequest" />
<oxm:class-to-be-bound
name="com.zazzercode.eccount.server.ws.schemas.ServiceResponse" />
<oxm:class-to-be-bound
name="com.zazzercode.eccount.server.ws.schemas.EccountMapEntry" />
<oxm:class-to-be-bound
name="com.zazzercode.eccount.server.ws.schemas.EccountServiceStatus" />
</oxm:jaxb2-marshaller>

<bean id="eccountServiceEndpoint"
class="com.zazzercode.eccount.server.ws.endpoints.EccountServiceEndpoint">
<constructor-arg ref="wsRequestProcessingApi" />
</bean>

</beans>



REFERENCES
3.6. Implementing the Endpoint, http://static.springsource.org/spring-ws/sites/2.0/reference/html/tutorial.html

Spring Web Services: SOAP vs. REST by Sam Brannen, http://www.slideshare.net/sbrannen/spring-web-services-soap-vs-rest

No comments:

Post a Comment