Wednesday, 9 September 2015

Spring Web services - client



Web service client

In this section we will build a web service client which would invoke a weather service and display weather information on the console. This would be a contract first web service where in we would get the WSDL from the service provider and build a client to consume the service.
We would be consuming the weather service web service hosted by http://www.webservicex.net. We would need the following tools to build our web service
  1. Spring tool suite: Get it from here
  2. Apache Maven: Get it from here
If you are new to maven you can go through the following tutorials. Maven tutorials.
Following are the steps to build a web service client. You can find the code that I have written here. GitHub - Weather service client
1. Getting the WSDL: You can download the WSDL from here. WSDL .
2. Folder structure of our application:



3. POM files for XML and core module: We would need to get spring dependencies and JAXB dependencies in order to build our web service. Following are the maven configuration for the XML and core module. 

POM for XML module:

Once we get the WSDL we need to get the java code to make web service calls. We also need the JAXB equivalent code. We would be using jaxb2-maven-plugin to achieve this.

<?xml version="1.0"?>
<project
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
 xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <!--POM for WeatherServiceClient xml module. Karthik Arun (karthikarun@outlook.com) -->
 <modelVersion>4.0.0</modelVersion>
 <parent>
  <artifactId>WeatherServiceClient-pom</artifactId>
  <groupId>com.karthik.spring.learning.weatherservice</groupId>
  <version>1.0-SNAPSHOT</version>
 </parent>
 <artifactId>WeatherServiceClient-xml</artifactId>
 <name>WeatherServiceClient-xml</name>
 <packaging>jar</packaging>
 <build>
  <resources>
   <resource>
    <directory>src/main/resources</directory>
    <includes>
     <include>**/*.properties</include>
    </includes>
    <filtering>true</filtering>
   </resource>
   <resource>
    <directory>src/main/resources</directory>
    <excludes>
     <exclude>**/*.properties</exclude>
    </excludes>
   </resource>
  </resources>
  <plugins>
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
     <target>1.7</target>
     <source>1.7</source>
    </configuration>
   </plugin>
   <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxb2-maven-plugin</artifactId>
    <version>1.3.1</version>
    <executions>
     <execution>
      <id>xjc</id>
      <goals>
       <goal>xjc</goal>
      </goals>
     </execution>
    </executions>
    <configuration>
     <outputDirectory>src/main/generated</outputDirectory>
     <wsdl>true</wsdl>
     <xmlschema>false</xmlschema>
     <schemaDirectory>src/main/resources</schemaDirectory>
     <schemaFiles>WeatherService.wsdl</schemaFiles>
     <keep>true</keep>
    </configuration>
    <dependencies>
     <dependency>
      <groupId>com.sun.xml.bind</groupId>
      <artifactId>jaxb-impl</artifactId>
      <version>2.2.4</version>
     </dependency>
     <dependency>
      <groupId>javax.xml.bind</groupId>
      <artifactId>jaxb-api</artifactId>
      <version>2.2.4</version>
     </dependency>
    </dependencies>
   </plugin>
  </plugins>
 </build>
</project>

POM for Core module:

We would need the XML module to write code in CORE module so we have added a maven dependency here.
<?xml version="1.0"?>
<project
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
 xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <!--POM for WeatherServiceClient core module. Karthik Arun (karthikarun@outlook.com) -->
 <modelVersion>4.0.0</modelVersion>
 <parent>
  <artifactId>WeatherServiceClient-pom</artifactId>
  <groupId>com.karthik.spring.learning.weatherservice</groupId>
  <version>1.0-SNAPSHOT</version>
 </parent>
 <artifactId>WeatherServiceClient-core</artifactId>
 <version>1.0-SNAPSHOT</version>
 <name>WeatherServiceClient-core</name>
 <packaging>jar</packaging>
 <dependencies>
  <dependency>
   <groupId>com.karthik.spring.learning.weatherservice</groupId>
   <artifactId>WeatherServiceClient-xml</artifactId>
   <version>1.0-SNAPSHOT</version>
  </dependency>
 </dependencies>
</project>
     

POM for main project module:


This is the main project POM
<?xml version="1.0" encoding="UTF-8"?>
<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">
 <!--POM weather service WS client. Karthik Arun (karthikarun@outlook.com) -->
 <modelVersion>4.0.0</modelVersion>
 <artifactId>WeatherServiceClient-pom</artifactId>
 <packaging>pom</packaging>
 <version>1.0-SNAPSHOT</version>
 <groupId>com.karthik.spring.learning.weatherservice</groupId>
 <name>WeatherServiceClient</name>
 <dependencies>
  <dependency>
   <groupId>org.springframework.ws</groupId>
   <artifactId>spring-ws-core</artifactId>
   <version>2.1.4.RELEASE</version>
  </dependency>
  <dependency>
   <groupId>org.springframework.ws</groupId>
   <artifactId>spring-ws-security</artifactId>
   <version>2.1.4.RELEASE</version>
  </dependency>
  <dependency>
   <groupId>com.sun.xml.stream</groupId>
   <artifactId>sjsxp</artifactId>
   <version>1.0.2</version>
  </dependency>
  <dependency>
   <groupId>org.apache.ws.security</groupId>
   <artifactId>wss4j</artifactId>
   <version>1.6.5</version>
  </dependency>
 </dependencies>
 <modules>
  <module>xml</module>
  <module>core</module>
 </modules>
</project>
4. Spring configuration to configure the web service client:

Spring configuration

We make use of
org.springframework.ws.client.core.WebServiceTemplate
to define our web service template to make web service calls.
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd           
http://www.springframework.org/schema/tx 
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
 
 <!-- Spring config for weather service web service interface.
  Karthik Arun (karthikarun@outlook.com) -->
  
<bean id="WeatherServiceWSTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
 <property name="defaultUri" value="http://www.webservicex.net/globalweather.asmx"/>
 <property name="unmarshaller" ref="JaxbMarshaller"/>
 <property name="marshaller"   ref="JaxbMarshaller"/>
 <constructor-arg ref="soapMessageFactory"/>
</bean> 

<bean id="soapMessageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">
       <property name="soapVersion">
           <util:constant static-field="org.springframework.ws.soap.SoapVersion.SOAP_12"/>
       </property>
   </bean>
 
<bean id="JaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
 <property name="contextPaths">
  <list>
    <value>net.webservicex</value>
  </list>
 </property>
</bean>

   <context:annotation-config/>
   <context:component-scan base-package="com.karthik.spring.learning.weatherservice"/>
</beans>
    
5. Java program to call the web service.

Java Client program

We make use of the WebServiceTemplate that we have configured to make calls to the web service. The method marshallSendAndReceive from webservice template makes web service calls.
package com.karthik.spring.learning.weatherservice;

import net.webservicex.GetWeather;
import net.webservicex.GetWeatherResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.ws.client.core.WebServiceTemplate;

/**
 * <p>
 * Class to make a call to weather service web service and display output
 * </p>
 * 
 * @author Karthik
 * @version 1.0
 */
@Component(value = "weatherServiceClient")
public class WeatherServiceClientImpl {

 @Autowired()
 protected WebServiceTemplate weatherServiceClient;

 /**
  * <p>
  * Method to call Weather service WS
  * </p>
  * 
  * @param request
  * @return
  * @throws Exception
  */
 public GetWeatherResponse getweather(GetWeather request) throws Exception {
  GetWeatherResponse response = null;
  System.out.println(weatherServiceClient.getDefaultUri());
  response = (GetWeatherResponse) weatherServiceClient.marshalSendAndReceive(request);
  return response;
 }

 @SuppressWarnings("resource")
 public static void main(String[] args) {
  GetWeather weather = new GetWeather();
  weather.setCityName("New Delhi");
  weather.setCountryName("India");
  ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-weatherservice.xml");
  WeatherServiceClientImpl client = (WeatherServiceClientImpl) context.getBean("weatherServiceClient");
  try {
   System.out.println("Finding weather information for: " + weather.getCityName() + ", "
     + weather.getCountryName());
   GetWeatherResponse response = client.getweather(weather);
   if (response != null) {
    System.out.println("The weather information is: " + response.getGetWeatherResult());
   }
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   ((AbstractApplicationContext) context).registerShutdownHook();
  }
 }
} 
 

Run the program:







 
 
Additional Reading: Spring web service documentation
Full article at: http://www/allaboutjava.club

Video tutorial



Please post your comments or suggestions if any in the comments section.

http://karthikarun.in 

No comments:

Post a Comment