Tuesday, 18 November 2008

Spring Web Services Step by Step Guide

Web Service Design Principles
The focus of the proposed methodology is on design of service interfaces based on the design principles derived from the Design experience and the lessons learnt from the earlier implementations. Following is the brief description of each of the design principle that is considered, debated and accepted.
Completeness: Application Domain Functionality should be fully covered by the specific set of services. Cross functional services necessitates additional development and maintenance efforts.
Granularity: Services should be designed and developed for common functions that encourage opportunity to reuse. Additional services are implemented using the composition of core services and operations.
Coupling: The services implementations must be loosly coupled. This must be achieved by adopting the code to interface technique.
Clarity, Uniformity and Elegance: Services should have well defined semantics and should be easily understood to improve usability. Web Service interface should explicitly describe operations that the service performs, including the semantics of the parameters. Clarity can be improved using a suitable naming convention, and by including additional documentation that describes the semantics of each service and its operations. Uniformity of naming services, operations and parameters can significantly improve usability of interfaces and at the same time minimize ambiguity.
Design Methodology
Overview
The Service design methodology comes from the principle of Contract First approach. With Contract First approach the Service contracts are defined by covering the following aspects.
Interface Information Security Information Service Level Information Service Access Point
Service Description
Semantic Model
Data Types
Operations Security Mechanisms
Access Criteria and Restrictions
Information Security Marking Service Level Specifications
Network Requirements Service Access Point

Web Service Design Methodology
The Services Design methodology comprises of following steps.
A. Requirements Gathering
B. Domain Definition
C. Interface Definition
D. Interface Governance
E. SLA Governance


Development Methodology

Web Service Development Methodology
The Services development methodology comprises of following steps.
A. Create Reusable Project Template
B. Create Schema
C. Create Service Components
D. Create Service End Points

Setup Maven
Copy the Settings.xml attached into the following folders
.m2 folder.
Conf folder of the maven install folder.

How to Create a Project template?
This section helps you in creating the Spring WS project template. The command downloads the spring project template from the maven repository and installs it in the services folder.

C:\Projects\ANF\Services>mvn archetype:generate -DarchetypeGroupId=org.anfcorp.service -DarchetypeArtifactId=service-archetype -DarchetypeVersion=1.0-SNAPSHOT

This section creates the transforms the Spring project created using the archetype into an eclipse project. Run the following command from the folder created by the archtype command. In this case it is anfservice.
mvn eclipse:eclispe
Import the created projects into eclipse by selecting the “Existing Projects into workspace”.

The imported eclipse project must look similar to the following image.

The projects that require to be imported are:
a. Service Project
This is the parent project containing all the other folders. This project has the folders representing all the other folders such as DAO, Domain, Service and SpringWS. Importing this one project is sufficient if there is no requirement to build the other projects individually.
b. Service DAO
This project has all the DOA classes that are required to be used by the service implementation. This classes in the folder must ideally not contain any business logic and must only have the data access, data persistence and data mapper code.
c. Service Domain
This project will contain domain specific classes. This can be the service interface and the domain objects. The Service interface represents the business operations that will be made available as web services. The domain classes can fall in two categories which are the Schema generated classes and or Or the domain objects that are to be used in the service implementations.
d. Service-Service
This project will contain the Service implementations for the interfaces defined in the service interface. These service implementations are referred by the spring WS configuration file. There can be more than one implementation for the service interface which can be releasing the same interface for different business processes.
e. Service-SpringWS
This project will contain all the spring specific classes and all the spring framework supporting classes. The Endpoints are to be realized in this project.

Updating the POM files

Service Project
Replace the parent element of the pom as follows.

bootstrap
com.anfcorp
2.0

Service DAO
Replace the parent element of the pom as follows.

bootstrap-jar
com.anfcorp
2.0

Service Domain
Replace the parent element of the pom as follows.

bootstrap-jar
com.anfcorp
2.0

Service Service
Replace the parent element of the pom as follows.

bootstrap-jar
com.anfcorp
2.0

Service SpringWS
Replace the parent element of the pom as follows.

bootstrap-war
com.anfcorp
2.0

Import the Schema.
Schema is created using the Modelling tool, in this case it is Enterprise Architect. The creation of Schema is described in the other document.
The class files are generated are generated by the build process
Configure the Web.xml
Web.xml is required to be configured for the message dispatcher servlet. The Message Dispatcher Servlet is the first point to receive the service request and then delegates the request to the appropriate endpoint. The message dispatcher servlet is logic is declared using the *-servlet.xml which is explained in the next section.
The important section in the web.xml is:

spring-ws
org.springframework.ws.transport.http.MessageDispatcherServlet
transformWsdlLocations
true


Servlet-name element assigns the name to the Message dispatcher servlet. The name is an important attribute as the *-servlet.xml is prefixed with the name assigned here.
Servlet-class element maps the MessageDisptcherServlet to the servlet-name. This can be the spring framework specific class or can be extended and implemented for any reason.
The initialization Parameters in this case assigns to transform the WSDL location to the application context path.

Configure the Spring-ws-servlet
Spring-ws-servlet.xml is required to be configured for the message dispatcher servlet. The Message Dispatcher Servlet is the first point to receive the service request and then delegates the request to the appropriate endpoint. The Message Dispatcher servlet behaves as configured in this file.
The Elements that are configured in this file are:
a. End Point
b. Type of End Point Mapping
c. Service Class
d. WSDL generation
e. Schema
f. Marshalling Framework
EndPoint
Endpoints are the central concept in Spring-ws. Endpoint provides the access to business service interfaces. An Endpoint is responsible for interpreting the XML Request message and send the XML Response to the requestor. Spring-WS provides variety of endpoints and various ways to handle the XML request and response.
The most commonly used endpoint base class is PayloadEndpoint, Which provides an invoke operation to be extended.
The variants of the PayloadEndpoint’s are as listed below.
a. AbstractDomPayloadEndpoint: By extending this class to implement the endpoint, we can use the w3c dom Element hierarchy to handle the request and response.
b. AbstractMrashallingPayloadEndpoint: By using this type of Endpoint, a Marshalling framework can be used to handle the request and response XML.
c. AbstractValidatingMarshallingPayloadEndpoint: the subclasses of this can implement the validation error handling logic by implementing onValidationErrors
d. AbstractFaultCreatingValidatingMarshallingPayloadEndpoint: The subclasses of this type generate a SOAP fault whenever a validation error occurs. The error codes are resolved using the application Context message source.










Following is the GetBrandByIdEndpoint and GetBrandsEndpoint for Reference:

package com.anfcorp.rms.organisation.ws;


import javax.xml.bind.JAXBElement;

import org.springframework.oxm.Marshaller;
import org.springframework.ws.server.endpoint.AbstractMarshallingPayloadEndpoint;

import com.anfcorp.rms.service.OrganizationService;
import com.anfcorp.rms.service.domain.Brand;
import com.anfcorp.rms.service.jaxb.GetBrandByIdRequest;
import com.anfcorp.rms.service.jaxb.GetBrandByIdResponse;
import com.anfcorp.rms.service.jaxb.ObjectFactory;
import com.anfcorp.rms.service.jaxb.conversion.OrganizationJAXBDomainToSchemaConverter;
import com.anfcorp.rms.service.jaxb.conversion.OrganizationJAXBResponseCreator;

public class GetBrandByIdEndpoint extends AbstractMarshallingPayloadEndpoint {

private OrganizationService organizationService;
private OrganizationJAXBResponseCreator responseCreator = new OrganizationJAXBResponseCreator();

public GetBrandByIdEndpoint(OrganizationService organizationService, Marshaller marshaller) throws Exception {
super(marshaller);
this.organizationService = organizationService;
}

protected Object invokeInternal(Object unmarshalledPayload) throws Exception {
System.out.println("getBrandByIdEndpoint start");

// get data needed for service call parameters
JAXBElement getBrandByIdRequestJAXB = (JAXBElement)unmarshalledPayload;
GetBrandByIdRequest getBrandByIdRequest = getBrandByIdRequestJAXB.getValue();
Long id = getBrandByIdRequest.getId();

// call service
Brand brand = this.organizationService.getBrandById(id);

// convert the service response into schema objects and return
return responseCreator.createGetBrandByIdResponse(brand);
}
}




package com.anfcorp.rms.service.endpoints;

import java.util.List;

import org.springframework.oxm.Marshaller;
import org.springframework.ws.server.endpoint.AbstractMarshallingPayloadEndpoint;

import com.anfcorp.rms.service.OrganizationService;
import com.anfcorp.rms.service.domain.Brand;
import com.anfcorp.rms.service.jaxb.GetBrandByIdResponse;
import com.anfcorp.rms.service.jaxb.GetBrandsResponse;
import com.anfcorp.rms.service.jaxb.ObjectFactory;
import com.anfcorp.rms.service.jaxb.conversion.OrganizationJAXBDomainToSchemaConverter;
import com.anfcorp.rms.service.jaxb.conversion.OrganizationJAXBResponseCreator;

public class GetBrandsEndpoint extends AbstractMarshallingPayloadEndpoint {

private OrganizationService organizationService;
private OrganizationJAXBResponseCreator responseCreator = new OrganizationJAXBResponseCreator();

public GetBrandsEndpoint(OrganizationService organizationService,
Marshaller marshaller) throws Exception {
super(marshaller);
System.out.println("I am in the constructor");
this.organizationService = organizationService;
System.out.println("I am done here");
}

protected Object invokeInternal(Object unmarshalledPayload) throws Exception {
System.out.println("getBrandByIdEndpoint start");

// call service
List brands = this.organizationService.getBrands();

return responseCreator.createGetBrandsResponse(brands);
}

}


EndPoint Mapping
The EndpointMapping configures the chain of invocation when the request is received by the message dispatcher servlet. When the request is received by the MessageDispatcher servlet it will hand it over to the endpoint mapping to create an instance of the EndpointInvocationChain. The MessageDisptacher will invoke the endpoint and any interceptor configured in the chain as show in the sequence diagram above.
Endpoint mappings generally inherit from the AbstractEndpointMapping. This offers an interceptor property.
The types of Endpoint mapping’s are:
a. PayloadRootQNameEndpointmapping: The PayloadRootQNameEndpointMapping will use the qualified name of the root element of the request payload to determine the endpoint that handles it.
b. SOAPActionEndpointMapping: You can use the SOAPAction HTTP header to route the messages.
c. MethodEndpointMapping: This Endpoint allows you to Handle multiple requests to one Endpoint class.
a. PayloadAnnotationMethodEndpointMapping: uses the @payloadRoot annotation with localpart and namespace element.
b. SoapActionAnnotationMethodEndpointMapping: uses the @SoapAction annotation to mark methods with a particular SOAPAction.




getBrandByIdEndpoint
getBrandsEndpoint







Service Class
The Service class is the business service which provides the implementation of the business service. This Business service is invoked by the endpoint class as like a regular java object.
It is declared in the *-servlet.xml as follows:


Following is the Java Service Implementation

package com.anfcorp.rms.service.service;

import java.util.List;

import com.anfcorp.rms.service.OrganizationService;
import com.anfcorp.rms.service.dao.OrganizationDAO;
import com.anfcorp.rms.service.dao.OrganizationDAOImpl;
import com.anfcorp.rms.service.domain.Brand;

public class OrganizationServiceImpl implements OrganizationService{
OrganizationDAO organizationDAO = new OrganizationDAOImpl();

public Brand getBrandById(Long id) {
return organizationDAO.getBrandById(id);
}

public List getBrands() {
return organizationDAO.getBrands();
}
}

WSDL Generation
A service contract is generally expressed as a WSDL file. In Spring-WS, generating the WSDL is based on the XSD and following few standard conventions.








The bean id determines the URL where the WSDL can be retrieved. In this case, the bean id is “organization”, which means that the WSDL can be retrieved as orginisation.wsdl in the servlet context path.
The schema property refers to the Messages.xsd.
We define the PortType to be OrganisationResource.
LocationURI sets the location where the service can be reached “/organisationService”
With TargetNamespace attribute you define the targetNamespace for the WSDL definition.
Schema
The Schema is used by the WSDL generation.




Marshalling Framework
Marshalling Framework serializes object to XML, and an unmarshaller desrializes XML stream to an Object.
Marshallers can be configured using tags from the oxm namespace.
The Marshallers that are supported
a. Jaxb1Marshaller: The Jaxb1Marshaller class implements Marshaller and UnMarshaller interface form the spring framework.




b. Jaxb2Marshaller: The Jaxb2Marshaller class behaves the same as Jaxb1Marsahller except that it supports classesToBeBound Property.





Complete Project File:
Please find the attached zip file which can be used for prototyping.

The Deployable war is as attached.


Appendix

Configuring Marshalling Frameworks
a. Castor: Castor implements Marshaller and UnMarshaller interface form the spring framework.


b. XMLBeans: XMLBeans implements Marshaller and UnMarshaller interface form the spring framework.


c. Jibx: JIBX implements Marshaller and UnMarshaller interface form the spring framework.

com.anfcorp.organisation.schema.Brand


d. XStream: The XStreamMarshaller does not require any configuration, and can be configured in an application context directly. To further customize the XML, you can set an alias map, which consists of string aliases mapped to classes:



com.anfcorp.organisation.schema.Brand


1 comment:

Anonymous said...

I learn something more challenging on different blogs everyday. I feel fervently about this and I like learning about this subject. If possible, as you gain information, please update this blog with more.
domain name web hosting