Spring Web Services using JAXB part-2

After the part-1 this is the contd part of it, now we are going to write the endpoint implementations and mapping these end points to the request from the web. so lets not waste time just jumping into the implementation part here we go.

Lets write AbstractPersonEndPoint class which will extend AbstractMarshallingPayloadEndpoint of Spring framework. Here we are going to just create PersonService object and define an abstract method invokeInternal of AbstractMarshallingPayloadEndpoint class.

/**
 * 
 */
package com.spark.springws.abstrct.endpoint;

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

import com.spark.springws.service.PersonService;

/**
 * @author Sony
 *
 */
public abstract class AbstractPersonEndPoint extends AbstractMarshallingPayloadEndpoint {

	protected PersonService personService;
	
	/**
	 * @param personService the personService to set
	 */
	public void setPersonService(PersonService personService) {
		this.personService = personService;
	}


	/* (non-Javadoc)
	 * @see org.springframework.ws.server.endpoint.AbstractMarshallingPayloadEndpoint#invokeInternal(java.lang.Object)
	 */
	@Override
	protected abstract Object invokeInternal(Object request) throws Exception;

}

Now its time to create concrete endpoint classes which will have exact business logic implementation and will extend AbstractPersonEndPoint. I will show for one of the service and other implementations are left for you.

/**
 * 
 */
package com.spark.springws.endpoints;

import org.springws.beans.schema.AddPersonRequest;

import com.spark.springws.abstrct.endpoint.AbstractPersonEndPoint;

/**
 * @author Sony
 *
 */
public class AddPersonEndPoint extends AbstractPersonEndPoint {

	/* (non-Javadoc)
	 * @see com.spark.springws.abstrct.endpoint.AbstractPersonEndPoint#invokeInternal(java.lang.Object)
	 */
	@Override
	protected Object invokeInternal(Object request) throws Exception {

		AddPersonRequest addPersonRequest = (AddPersonRequest) request;
		personService.addPerson(addPersonRequest.getPerson());
		return null;
	}

}

now lets take a look at the spring-ws-servlet.xml which we already defined in this part-1 section and modify it a little bit as shown below.

<?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:oxm="http://www.springframework.org/schema/oxm"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
		http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.2.xsd">

	<bean id="personService" class="com.spark.springws.service.impl.PersonServiceImpl"
		init-method="initialize" />
	<bean id="Person"
		class="org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition">
		<property name="schema" ref="schema" />
		<property name="portTypeName" value="Person" />
		<property name="locationUri" value="/services" />
		<property name="targetNamespace" value="http://www.example.org/person/schema" />
	</bean>
	<bean id="schema" class="org.springframework.xml.xsd.SimpleXsdSchema">
		<property name="xsd" value="/WEB-INF/xsd/schemas/Person.xsd" />
	</bean>

	<bean id="validationInterceptor"
		class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor">
		<property name="xsdSchema" ref="schema"></property>
		<property name="validateRequest" value="true" />
		<property name="validateResponse" value="true" />
	</bean>

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

	<oxm:jaxb2-marshaller id="marshaller"
		contextPath="org.springws.beans.schema" />
	<oxm:jaxb2-marshaller id="unmarshaller"
		contextPath="org.springws.beans.schema" />

	<bean id="addPersonEndpoint" class="com.spark.springws.endpoints.AddPersonEndPoint"
		autowire="byName" />
	<bean id="getAllPersonsEndpoint" class="com.spark.springws.endpoints.GetAllPersonsEndPoint"
		autowire="byName" />
	<bean id="getPersonEndpoint" class="com.spark.springws.endpoints.GetPersonEndPoint"
		autowire="byName" />

	<bean name="endpointMapping"
		class="org.springframework.ws.server.endpoint.mapping.PayloadRootQNameEndpointMapping">
		<property name="interceptors">
			<list>
				<ref local="loggingInterceptor" />
				<ref local="validationInterceptor" />
			</list>
		</property>
		<property name="mappings">
			<props>
				<prop key="{http://www.example.org/person/schema}AddPersonRequest">addPersonEndpoint</prop>
				<prop key="{http://www.example.org/person/schema}GetAllPersonsRequest">getAllPersonsEndpoint</prop>
				<prop key="{http://www.example.org/person/schema}GetPersonRequest">getPersonEndpoint</prop>
				<prop key="{http://www.example.org/person/schema}UpdatePersonRequest">updatePersonEndpoint</prop> 
					<prop key="{http://www.example.org/person/schema}DeletePersonRequest">deletePersonEndpoint</prop>
			</props>
		</property>
	</bean>

	<bean id="exceptionResolver"
		class="org.springframework.ws.soap.server.endpoint.SoapFaultMappingExceptionResolver">
		<property name="defaultFault" value="SERVER" />
		<property name="exceptionMappings">
			<props>
				<prop key="org.springframework.oxm.ValidationFailureException">CLIENT,Invalid request</prop>
				<prop key="com.spark.springws.custom.exception.PersonException">SERVER</prop>
			</props>
		</property>
	</bean>
</beans>

once this is done just deploy the project and test the request and response from SOAP UI as shown below.
add-request

get-req-res

Happy Spring-Web services 🙂

Advertisements

Consuming web service using Spring 3.x

Hi guys, Here i am going to demonstrate how to consume web service using spring framework.Consuming web services with Spring framework is amazingly easy. It avoids the need of creating client side stubs during compile time and does the same at run time. A typical web service client can be configured as shown below-

inorder to get the spring capability for webservice please add the following dependencies to pom.xml as below-

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.spark.spring.webservice</groupId>
  <artifactId>SpringWebService</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>SpringWebService</name>
  <description>SpringWebService</description>
  
  <dependencies>
  	<dependency>
  		<groupId>org.springframework</groupId>
  		<artifactId>spring-core</artifactId>
  		<version>3.1.1.RELEASE</version>
  	</dependency>
  	<dependency>
  		<groupId>org.springframework</groupId>
  		<artifactId>spring-context</artifactId>
  		<version>3.1.1.RELEASE</version>
  	</dependency>
  	<dependency>
  		<groupId>org.springframework</groupId>
  		<artifactId>spring-context-support</artifactId>
  		<version>3.1.1.RELEASE</version>
  	</dependency>
  	<dependency>
  		<groupId>org.springframework</groupId>
  		<artifactId>spring-beans</artifactId>
  		<version>3.1.1.RELEASE</version>
  	</dependency>
  	<dependency>
  		<groupId>org.springframework.ws</groupId>
  		<artifactId>spring-ws-core</artifactId>
  		<version>2.1.1.RELEASE</version>
  	</dependency>
  </dependencies>
</project>

please configure your applicationContext.xml as below-

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

	<bean id="myWebService"
		class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
		<property name="serviceInterface" value="com.spark.webservice.TemperatureConverter" />
		<property name="wsdlDocumentUrl" value="http://localhost:8080/JBossWebServices?wsdl" />
		<property name="namespaceUri" value="http://impl.webservice.spark.com/" />
		<property name="serviceName" value="TemperatureConverter" />
		<property name="portName" value="TemperatureConverterImplPort" />
	</bean>

</beans>

Where serviceInterface is the business interface that clients will use for invoking service methods. wsdlDocumentUrl is the URL for the published WSDL file. Spring will download WSDL from the given URL and generate the client side stubs when it creates the bean usually during application start up. namespaceUri corresponds to the targetNamespace in the .wsdl file. serviceName corresponds to the service name in the .wsdl file. portName corresponds to the port name in the .wsdl file.

Note Please refer to my previous port to get the wsdl file.

Now accessing web service pretty easy, just get the bean from Spring context and use that to invoke methods-

/**
 * 
 */
package com.spark.spring.webservice.client;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.spark.webservice.TemperatureConverter;

/**
 * @author Sony
 *
 */
public class SpringWebserviceClient {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		TemperatureConverter converter = (TemperatureConverter)applicationContext.getBean("myWebService");
		System.out.println(converter.convertCelsiusToFahrenheit(42.0));
	}

}

inorder to use the service we need to create the service interface type as below –

/**
 * 
 */
package com.spark.webservice;

import javax.jws.WebMethod;
import javax.jws.WebService;

/**
 * @author Sony
 *
 */
@SuppressWarnings("restriction")
@WebService
public interface TemperatureConverter {

	@WebMethod
	public double convertCelsiusToFahrenheit(double value);
	@WebMethod
	public double convertFahrenheitToCelsius(double value);
}

Thats it now run the main method and get the result.
Note: the service should be up and running in the server.

Happy Coding 🙂