ArtsAutosBooksBusinessEducationEntertainmentFamilyFashionFoodGamesGenderHealthHolidaysHomeHubPagesPersonal FinancePetsPoliticsReligionSportsTechnologyTravel

Spring Web Service

Updated on December 1, 2014

Spring Web Service

I will assume that you are aware with Spring and basics of web service. I will show you how to develop web service using Spring.

Spring uses contract-first approach for developing web service. Contract-first means first you develop XMl and then java.

Advantages of Contract First approach:

a) Object/XML impedance mismatch (E.g. Date of XMl and Java. XSD date type represents a year, month, and day. If we call this service from Java, we will probably use either a

java.util.Date

or

java.util.Calendar

. Actually both describe times, rather than dates. So, we will actually end up sending data that represents the 20th of July 2009 at midnight (

2009-07-20T00:00:00

), which is not the same as

2009-07-20

.)

b) Performance : An object might reference another object, which refers to another, etc. In the end, half of the objects on the heap in your virtual machine might be converted into XML, which will result in slow response times. When using contract-first, you explicitly describe what XML is sent where, thus making sure that it is exactly what you want.

c) Reusability : You can use one xsd element or elements in other xsd.

Now first we will start with XML/XSD followed by Java implementation.

I am taking simple example of Train booking request. Step by step I will explain how to develop spring web service. First we will create sample XML.

1) TrainRequest.xml

<TrainRequest>

<TrainDetails>

<TrainNumber>1556<TrainNumber> <JourneyDate>2009-07-25<JourneyDate>

<From>Pune<From>

<To>Dadar<To>

</TrainDetails>

<PassengerDetails >

<NumberOfPassengers></NumberOfPassengers>

<MasterPassenger>

<Name>Chirag shah</Name>

<Age>25</Age>

<Sex></Sex>

</MasterPassenger>

</PassengerDetails>

</TrainRequest>

2) Now we will generate XSD from xml using tool. By far the easiest way to create an XSD is to infer it from sample documents. Any good XML editor or Java IDE offers this functionality. Basically, these tools use some sample XML documents, and generate a schema from it that validates them all. The end result certainly needs to be polished up, but it's a great starting point.

This is our polished and final XSD which we will use further.

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:train="http://sample.com/tr/schemas"
elementFormDefault="qualified"
targetNamespace="http://sample.com/tr/schemas">
<xs:element name="TrainRequest">
<xs:complexType>
<xs:all>
<xs:element name="TrainDetails" type="train:TrainDetails"/> 
<xs:element name="PassengerDetails" type="train:PassengerDetails"/>
</xs:all>
</xs:complexType>
</xs:element>
<xs:complexType name="TrainDetails">
<xs:sequence>
<xs:element name="TrainNumber" type="xs:integer"/>
<xs:element name="JourneyDate" type="xs:date"/>
<xs:element name="To" type="xs:string"/> 
<xs:element name="From" type="xs:string"/> 
</xs:sequence> 
</xs:complexType>
<xs:complexType name="PassengerDetails">
<xs:sequence>
<xs:element name="NumberOfPassengers" type="xs:integer"/>
<xs:element name="MasterPassenger" type="train:masterPassenger" minOccurs="1" maxOccurs="1"/> 
</xs:sequence> 
</xs:complexType>
<xs:complexType name="masterPassenger">
<xs:sequence>
<xs:element name="Name" type="xs:string" minOccurs="1"/>
<xs:element name="Age" type="xs:integer" minOccurs="1"/>
<xs:element name="Sex" type="xs:string" minOccurs="1"/>
</xs:sequence>
</xs:complexType>
<xs:element name="TrainResponse">
<xs:complexType>
<xs:all>
<xs:element name="Code" type="xs:string" minOccurs="1"/> 
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>

3) Now third is WSDL. We will not write wsdl with own because spring internally generates WSDL for us using configuration specified in context file. We will talk about context file in next section.

4) I have used maven for project build tool. I have generated one project called “railwayService” using maven and added following dependency in pom.xml which we will need to develop spring web service.

<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-oxm</artifactId>
<version>1.5.7</version>
</dependency>
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws-core</artifactId>
<version>1.5.7</version>
</dependency>
<dependency>
<groupId>jdom</groupId>
<artifactId>jdom</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>javax.xml.soap</groupId>
<artifactId>saaj-api</artifactId>
<version>1.3</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.sun.xml.messaging.saaj</groupId>
<artifactId>saaj-impl</artifactId>
<version>1.3</version>
<scope>runtime</scope>
</dependency>

5) Now Its time to develop Endpoint. I am using XPATH for navigation in xml and Jdom for xml parsing.

package com.test;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Namespace;
import org.jdom.xpath.XPath;
import org.springframework.ws.server.endpoint.AbstractJDomPayloadEndpoint;

public class RailwayEndpoint extends AbstractJDomPayloadEndpoint {

	private XPath trainNumberExpression;
	
	private XPath journeyDateExpression;

	private XPath toExpression;
	
    private XPath fromExpression;

    private XPath numberOfPassengersExpression;
    
    private XPath nameExpression;

    private XPath ageExpression;
    
    private XPath sexExpression;

    private final RailwayService railwayService;

    public RailwayEndpoint(RailwayService railwayService) throws JDOMException {
    	System.out.println("Entered in constructor");
        this.railwayService = railwayService;
        Namespace namespace = Namespace.getNamespace("tr", "http://sample.com/tr/schemas");
        
        trainNumberExpression = XPath.newInstance("//tr:TrainNumber");
        trainNumberExpression.addNamespace(namespace);
        
        journeyDateExpression = XPath.newInstance("//tr:JourneyDate");
        journeyDateExpression.addNamespace(namespace);
        
        toExpression = XPath.newInstance("//tr:To");
        toExpression.addNamespace(namespace);
        
        fromExpression = XPath.newInstance("//tr:From");
        fromExpression.addNamespace(namespace);
        
        numberOfPassengersExpression = XPath.newInstance("//tr:NumberOfPassengers");
        numberOfPassengersExpression.addNamespace(namespace);
        
        nameExpression = XPath.newInstance("//tr:Name");
        nameExpression.addNamespace(namespace);
        
        ageExpression = XPath.newInstance("//tr:Age");
        ageExpression.addNamespace(namespace);
        
        sexExpression = XPath.newInstance("//tr:Sex");
        sexExpression.addNamespace(namespace);
    }

    protected Element invokeInternal(Element railwayRequest) throws Exception {    
    	System.out.println("Entered in invokeInternal");
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        
        BookingDetail bookingDetail = new BookingDetail();
        
        Integer trainNumber = Integer.parseInt(trainNumberExpression.valueOf(railwayRequest));
        bookingDetail.setTrainNumber(trainNumber);
        Date journeyDate = dateFormat.parse(journeyDateExpression.valueOf(railwayRequest));
        bookingDetail.setJourneyDate(journeyDate);
        String destination = toExpression.valueOf(railwayRequest);
        bookingDetail.setDestination(destination);
        String source = fromExpression.valueOf(railwayRequest);
        bookingDetail.setSource(source);
        Integer noOfPass = Integer.parseInt(numberOfPassengersExpression.valueOf(railwayRequest));
        bookingDetail.setNoOfPass(noOfPass);
        String name = nameExpression.valueOf(railwayRequest);
        bookingDetail.setName(name);
        Integer age = Integer.parseInt(ageExpression.valueOf(railwayRequest));
        bookingDetail.setAge(age);
        String sex = sexExpression.valueOf(railwayRequest);
        bookingDetail.setSex(sex);

        String responseMessage = railwayService.bookHoliday(bookingDetail);
        return generateResponse(responseMessage);
    }
    
	private Element generateResponse(String message) 
	{
		System.out.println("Entered in generateResponse");
		Element response = null;
		Namespace respNamespace = Namespace.getNamespace("tr", "http://sample.com/tr/schemas");
		try {
			Element msgResponseRoot = new Element("TrainResponse",
					respNamespace);

			Element messageElement = new Element("Code", respNamespace);
			messageElement.addContent(message);
			msgResponseRoot.addContent(messageElement);

			response = new Document(msgResponseRoot).getRootElement();
		} catch (Exception e) {
			System.out.println("Error rsponse writing");
		}
		return response;
	}
}

- In above endpoint example I am using AbstractJDomPayloadEndpoint because I don’t need or bother about soap header. There are two types of endpoints 1) Message Endpoints 2) payload endpoints.

The RailwayEndpoint requires the RailwayService business service to operate, so we inject the dependency via the constructor. Next, we have used XPath expressions using the JDOM API. There are eight expressions which will be used to extracting the required parameters.

- The invokeInternal(...) method is a template method, which gets passed with the

<RailwayRequest/> element from the incoming XML message. We use the XPath expressions to extract the string values from the XML messages. With these values, we invoke a method on the business service. Typically, this will result in a finding seat availability, allotment of seats and so on. Finally, we return Success or Failure response according to user’s inputs.

We have returned a JDOM Element that represents the payload of the response message.

6) Now we will create context file. First we will register our endpoint class in railway-ws-servlet.xml like:

<bean id="railwayEndpoint" class="com.test.RailwayEndpoint">

<constructor-arg ref="railwayService"/>

</bean>

<bean id="railwayService" class="com.test.RailwayService"/>

Now we will add configuration for routing messages to the endpoint.

<bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootQNameEndpointMapping">

<property name="mappings">

<props>

<prop key="{http://sample.com/tr/schemas}TrainRequest">railwayEndpoint</prop>

</props>

</property>

<property name="interceptors">

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

</property>

</bean>

This means that whenever any XML message is received with the namespace http://sample.com/tr/schemas and the TrainRequest local name, it will be routed to the railwayEndpoint. We have used PayloadLoggingInterceptor interceptor which will dumps incoming and outgoing messages to the log.

At last we will add configuration for publishing WSDL.

<bean id="railway" class="org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition">

<property name="schema" ref="schema"/>

<property name="portTypeName" value="RailwayResource"/>

<property name="locationUri" value="/railwayService/"/> <property name="targetNamespace" value="http://sample.com/tr/definitions"/>

</bean>

<bean id="schema" class="org.springframework.xml.xsd.SimpleXsdSchema">

<property name="xsd" value="/WEB-INF/trainRequest.xsd"/>

</bean>

bean id: determines the URL where the WSDL can be retrieved. http://localhost:8080/railwayService/railway.wsdl.

schema : this property refers schema that we have created.

portTypeName: WSDL port type which is RailwayResource

locationUri: We set the location where the service can be reached: /railwayService/. We use a a relative URI and we instruct the framework to transform it dynamically to an absolute URI. Hence, if the service is deployed to different contexts we don't have to change the URI manually.

targetNamespace: Finally, we define the target namespace for the WSDL definition itself. Setting these is not required. If not set, we give the WSDL the same namespace as the schema.

7) Create a war file and deploy application. I am using tomcat server. Point your browser to http://localhost:8080/railwayRequest/railway.wsdl. This WSDL is ready to be used by clients, such as soapUI, or other SOAP frameworks.

How to access it using SOAP UI.

Steps for using this WSDL in SOAP UI.

- Start SOAP UI and create new Project. Go through first image .
- Click Ok and your wsdl is ready for use. Now add entries to request parameters like below second image .
- Now click on top center text box and make it http://localhost:/railwayService.
Then click on left top blue arrow button. You will receive a response something like below third image.

Have u ever used ibotta app for rebate? Try it..Use aydtcuy and you will be added to my team, we can earn fast by making team and generating bonus..Worth it..

first
first
second
second
third
third

© 2009 chirag272003

working

This website uses cookies

As a user in the EEA, your approval is needed on a few things. To provide a better website experience, hubpages.com uses cookies (and other similar technologies) and may collect, process, and share personal data. Please choose which areas of our service you consent to our doing so.

For more information on managing or withdrawing consents and how we handle data, visit our Privacy Policy at: https://corp.maven.io/privacy-policy

Show Details
Necessary
HubPages Device IDThis is used to identify particular browsers or devices when the access the service, and is used for security reasons.
LoginThis is necessary to sign in to the HubPages Service.
Google RecaptchaThis is used to prevent bots and spam. (Privacy Policy)
AkismetThis is used to detect comment spam. (Privacy Policy)
HubPages Google AnalyticsThis is used to provide data on traffic to our website, all personally identifyable data is anonymized. (Privacy Policy)
HubPages Traffic PixelThis is used to collect data on traffic to articles and other pages on our site. Unless you are signed in to a HubPages account, all personally identifiable information is anonymized.
Amazon Web ServicesThis is a cloud services platform that we used to host our service. (Privacy Policy)
CloudflareThis is a cloud CDN service that we use to efficiently deliver files required for our service to operate such as javascript, cascading style sheets, images, and videos. (Privacy Policy)
Google Hosted LibrariesJavascript software libraries such as jQuery are loaded at endpoints on the googleapis.com or gstatic.com domains, for performance and efficiency reasons. (Privacy Policy)
Features
Google Custom SearchThis is feature allows you to search the site. (Privacy Policy)
Google MapsSome articles have Google Maps embedded in them. (Privacy Policy)
Google ChartsThis is used to display charts and graphs on articles and the author center. (Privacy Policy)
Google AdSense Host APIThis service allows you to sign up for or associate a Google AdSense account with HubPages, so that you can earn money from ads on your articles. No data is shared unless you engage with this feature. (Privacy Policy)
Google YouTubeSome articles have YouTube videos embedded in them. (Privacy Policy)
VimeoSome articles have Vimeo videos embedded in them. (Privacy Policy)
PaypalThis is used for a registered author who enrolls in the HubPages Earnings program and requests to be paid via PayPal. No data is shared with Paypal unless you engage with this feature. (Privacy Policy)
Facebook LoginYou can use this to streamline signing up for, or signing in to your Hubpages account. No data is shared with Facebook unless you engage with this feature. (Privacy Policy)
MavenThis supports the Maven widget and search functionality. (Privacy Policy)
Marketing
Google AdSenseThis is an ad network. (Privacy Policy)
Google DoubleClickGoogle provides ad serving technology and runs an ad network. (Privacy Policy)
Index ExchangeThis is an ad network. (Privacy Policy)
SovrnThis is an ad network. (Privacy Policy)
Facebook AdsThis is an ad network. (Privacy Policy)
Amazon Unified Ad MarketplaceThis is an ad network. (Privacy Policy)
AppNexusThis is an ad network. (Privacy Policy)
OpenxThis is an ad network. (Privacy Policy)
Rubicon ProjectThis is an ad network. (Privacy Policy)
TripleLiftThis is an ad network. (Privacy Policy)
Say MediaWe partner with Say Media to deliver ad campaigns on our sites. (Privacy Policy)
Remarketing PixelsWe may use remarketing pixels from advertising networks such as Google AdWords, Bing Ads, and Facebook in order to advertise the HubPages Service to people that have visited our sites.
Conversion Tracking PixelsWe may use conversion tracking pixels from advertising networks such as Google AdWords, Bing Ads, and Facebook in order to identify when an advertisement has successfully resulted in the desired action, such as signing up for the HubPages Service or publishing an article on the HubPages Service.
Statistics
Author Google AnalyticsThis is used to provide traffic data and reports to the authors of articles on the HubPages Service. (Privacy Policy)
ComscoreComScore is a media measurement and analytics company providing marketing data and analytics to enterprises, media and advertising agencies, and publishers. Non-consent will result in ComScore only processing obfuscated personal data. (Privacy Policy)
Amazon Tracking PixelSome articles display amazon products as part of the Amazon Affiliate program, this pixel provides traffic statistics for those products (Privacy Policy)
ClickscoThis is a data management platform studying reader behavior (Privacy Policy)