Spring Web Services Client

In this post we’ll develop a Spring WebService client which will consume the Webservice we created in the previous post, getSquareService. This getSquareService takes in an integer as an input and gives back its square via http using spring web services 2.0. Earlier we used a Soap UI, to test and send/recieve our request/response, but now we’ll develop our own client as in real applications.

This client will be a normal Spring MVC application. As far as content is concerned, we’ll use two things here:-

  1. Web Service Template by Spring: This web service templates, makes our client code, extremely easy and good. It’s a helper template just as in JDBCTemplate, which is to access database using jdbc.
  2. wsimport tool by JAX-WS: This tool, takes in the wsdl url, and generates the Java Proxy classes and other artifacts which are necessary to consume the webservice.

Let’s start developing our client to the webservice. You don’t have to copy paste, the source code is shared and can be downloaded easily.

Download source code.

You can see the older version from here. The current version incorporates the changes required to comply with Maven 3

Now, since you have the source code at your disposal, let’s start it from the very beginning 🙂

Developing the Web Service Client from scratch!

1. Download the webservice project created in the earlier post Spring Web Services 2. Made Easy! and import it using Existing Maven Projects in your STS/Eclipse. (I use SpringSourceToolSuite, STS in short, though!)

2. Now open up your browser and type in the following URL to see the WSDL generated and examine it.

http://localhost:8080/spring-ws2-exemplary/getSquare.wsdl

3. Download the wsimport tool and execute it by following the instructions and set the path of it’s bin folder in your classpath.

4. Now we’ll use wsimport tool to generate our Java classes, as we generated it for jaxb.

5. Open command prompt and enter the following command to generate the classes at some place.

wsimport -d F:\generated -keep http://localhost:8080/spring-ws2-exemplary/getSquare.wsdl

Make sure the target directory already exists. Below is the screeen shot of this command.

Now check at the target place for the files generated, F:\Generated in my case.

6. Create the project by executing the following command in a single line.

mvn archetype:generate -DgroupId=ankeet.ws2.client -DartifactId=spring-ws2-client -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false

7. Open your STS/Eclipse and import the above as Existing Maven Projects. This import option will come only if you have maven plugin installed for your IDE. With STS it comes in built, but you need to install it explicitly for Eclipse. Else do an mvn eclipse:eclipse and then import as Existing Projects in workspace.

8. Create a new source folder and in it a package com.wordpress.ankeetmaini.spring_ws2_square and copy all the .java files created earlier by wsimport.

9. Create another package ankeet.spring.ws2.controller, where we’ll create the Controller of our Client App. Call it ClientController.java

/**</pre>
 *
 */
package ankeet.spring.ws2.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.ws.client.core.WebServiceTemplate;

import com.wordpress.ankeetmaini.spring_ws2_square.ObjectFactory;
import com.wordpress.ankeetmaini.spring_ws2_square.SquareServiceRequest;
import com.wordpress.ankeetmaini.spring_ws2_square.SquareServiceResponse;

/**
 * @author Ankeet Maini
 *
 */
@Controller
@RequestMapping("/")
public class ClientController {
 @Autowired
 private WebServiceTemplate webServiceTemplate;

 /**
 * This is the default handler. When application goes live
 * the control comes to this, and it fires a JSP,
 * asking the input.
 */
 @RequestMapping(method = RequestMethod.GET)
 public String getRequest(Model model) {
 model.addAttribute("squareServiceRequest", new ObjectFactory().createSquareServiceRequest());
 //Show request.jsp
 return "request";
 }

 /**
 * This is the handler, which takes in the input number, and calculates
 * the square by taking it from the webservice, via WebServiceTemplate, and then finally
 * sets as a ModelAttribute, which in turn is shown by "response.jsp"
 */
 @RequestMapping(method = RequestMethod.POST)
 public String showResponse(@ModelAttribute SquareServiceRequest squareServiceRequest, Model model) {
 //Creating the SquareServiceResponse object.
 SquareServiceResponse squareServiceResponse = new ObjectFactory().createSquareServiceResponse();
 //Sending the request object via WebServiceTemplate and getting back the response from WebService 🙂
 squareServiceResponse = (SquareServiceResponse) webServiceTemplate.marshalSendAndReceive(squareServiceRequest);
 //This was supposed to be a hard part. Piece of cake 🙂
 model.addAttribute("squareServiceResponse", squareServiceResponse);
 //Show response.jsp
 return "response";
 }

}
<pre>

10. Create a folder “views” inside WEB-INF to keep your JSP files. Inside the “views” folder create two JSP files:

  1. request.jsp    -> This will ask user a number whose square is to be calculated using WebService: getSquare.
  2. response.jsp -> This will show the user calculated square, which came in response from getSquare webservice.

request.jsp


<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
 pageEncoding="ISO-8859-1"%>
 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ page session="false" %>

<html>
<head>
<%@ page isELIgnored="false" %>
<title>Square Webservice 2 Client</title>
</head>
<body>
 <form:form commandName="squareServiceRequest" method="post">
 <table>
 <tr>
 <td>Enter Number:</td>
 <td><form:input path="input"/></td>
 <td><font color="red"><form:errors path="input"/></font></td>
 </tr>
 </table>
 <input name="submit" type="submit" value="Get it's square!" />
 </form:form>
</body>
</html>

response.jsp


<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
 pageEncoding="ISO-8859-1"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
<head>
<%@ page isELIgnored="false" %>
<title>Square Webservice 2 Client</title>
</head>
<body>
 The square of the entered number is: <b><font color="red" size="3">${squareServiceResponse.output}</font></b>
 <br />
 <br /> This is brought to you by <i>Spring Webservices 2</i> and <font color="blue" size="4.5"><b>Ankeet Maini</b></font> 🙂
</body>
</html>

11. Define your web.xml. Make sure web.xml is directly inside the WEB-INF.


<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
 <display-name>Archetype Created Web Application</display-name>
 <servlet>
 <servlet-name>spring-ws2-client</servlet-name>
 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
 <load-on-startup>1</load-on-startup>
 </servlet>

 <servlet-mapping>
 <servlet-name>spring-ws2-client</servlet-name>
 <url-pattern>/</url-pattern>
 </servlet-mapping>
</web-app>

12. Create your spring-ws2-client-servlet.xml


<?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:mvc="http://www.springframework.org/schema/mvc" xmlns:sws="http://www.springframework.org/schema/web-services"
 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/context
 http://www.springframework.org/schema/context/spring-context-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/mvc
 http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

 <!-- Activates various annotations to be detected in bean classes -->
 <context:annotation-config />

<!-- Scans the classpath for annotated components that will be auto-registered
 as Spring beans. For example @Controller and @Service. Make sure to set the
 correct base-package -->
 <context:component-scan base-package="ankeet.spring" />
 <context:component-scan base-package="com.wordpress" />

<!-- Configures the annotation-driven Spring MVC Controller programming
 model. Note that, with Spring 3.0, this tag works in Servlet MVC only! -->
 <mvc:annotation-driven />
 <!-- Declare a view resolver -->
 <bean id="viewResolver"
 class="org.springframework.web.servlet.view.InternalResourceViewResolver"
 p:prefix="/WEB-INF/views/" p:suffix=".jsp" />

 <bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate"
 p:marshaller-ref="jaxbMarshaller"
 p:unmarshaller-ref="jaxbMarshaller"
 p:defaultUri="http://localhost:8080/spring-ws2-exemplary/squareService"
 p:messageSender-ref="messageSender">
 <constructor-arg ref="messageFactory"/>
 </bean>
 <bean id="messageSender" class="org.springframework.ws.transport.http.CommonsHttpMessageSender"/>
 <bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"/>
 <bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller"
 p:contextPath="com.wordpress.ankeetmaini.spring_ws2_square"/>

</beans>

13. Lastly, define your POM.xml file so that maven can provide for all your dependencies.


<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/maven-v4_0_0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>ankeet.ws2.client</groupId>
 <artifactId>spring-ws2-client</artifactId>
 <packaging>war</packaging>
 <version>1.0-SNAPSHOT</version>
 <name>spring-ws2-client Maven Webapp</name>
 <url>http://maven.apache.org</url>
 <dependencies>
 <dependency>
 <groupId>javax.xml.bind</groupId>
 <artifactId>jaxb-api</artifactId>
 <version>2.0</version>
 </dependency>
 <dependency>
 <groupId>com.sun.xml.bind</groupId>
 <artifactId>jaxb-impl</artifactId>
 <version>2.0.3</version>
 </dependency>
 <dependency>
 <groupId>org.apache.xmlbeans</groupId>
 <artifactId>xmlbeans</artifactId>
 <version>2.4.0</version>
 </dependency>
 <dependency>
 <groupId>junit</groupId>
 <artifactId>junit</artifactId>
 <version>3.8.1</version>
 <scope>test</scope>
 </dependency>
 <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-beans</artifactId>
 <version>3.0.5.RELEASE</version>
 </dependency>
 <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-context</artifactId>
 <version>3.0.5.RELEASE</version>
 </dependency>
 <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-context-support</artifactId>
 <version>3.0.5.RELEASE</version>
 </dependency>
 <dependency>
 <groupId>org.springframework.ws</groupId>
 <artifactId>spring-ws-core</artifactId>
 <version>2.0.3.RELEASE</version>
 </dependency>
 <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-web</artifactId>
 <version>3.0.5.RELEASE</version>
 <type>jar</type>
 <scope>compile</scope>
 </dependency>
 <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-core</artifactId>
 <version>3.0.5.RELEASE</version>
 <type>jar</type>
 <scope>compile</scope>
 </dependency>
 <dependency>
 <groupId>log4j</groupId>
 <artifactId>log4j</artifactId>
 <version>1.2.14</version>
 <type>jar</type>
 <scope>compile</scope>
 </dependency>
 <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-tx</artifactId>
 <version>3.0.5.RELEASE</version>
 <type>jar</type>
 <scope>compile</scope>
 </dependency>
 <dependency>
 <groupId>jstl</groupId>
 <artifactId>jstl</artifactId>
 <version>1.1.2</version>
 <type>jar</type>
 <scope>compile</scope>
 </dependency>
 <dependency>
 <groupId>taglibs</groupId>
 <artifactId>standard</artifactId>
 <version>1.1.2</version>
 <type>jar</type>
 <scope>compile</scope>
 </dependency>
 <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-webmvc</artifactId>
 <version>3.0.5.RELEASE</version>
 <type>jar</type>
 <scope>compile</scope>
 </dependency>
 <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-aop</artifactId>
 <version>3.0.5.RELEASE</version>
 <type>jar</type>
 <scope>compile</scope>
 </dependency>

<dependency>
 <groupId>commons-httpclient</groupId>
 <artifactId>commons-httpclient</artifactId>
 <version>3.1</version>
 <type>jar</type>
 <scope>compile</scope>
 </dependency>
 </dependencies>
 <build>
 <finalName>spring-ws2-client</finalName>
 </build>
</project>

14. Check your directory structure. Make sure you are not missing anything, neither the resource, nor the structure.

15. To run this web client, first run the webservice, spring-ws2-exemplary project, download it from here.

16. Run the client now. The project is hosted on google codes. Download it from here. Now, run the client by importing it as Existing Maven Projects.

Enter the number, and press the button.

That’s all folks. If you come across any problem, do let me know, and if you do go a step further and do some improvements then do share it here, and I’ll incorporate into the post citing your name and contribution. 🙂

23 thoughts on “Spring Web Services Client”

  1. I am getting the following error. Any suggession
    HTTP Status 500 – Request processing failed; nested exception is org.springframework.ws.client.WebServiceTransportException: Not Found [404]

    ——————————————————————————–

    type Exception report

    message Request processing failed; nested exception is org.springframework.ws.client.WebServiceTransportException: Not Found [404]

    description The server encountered an internal error that prevented it from fulfilling this request.

    exception

    org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.ws.client.WebServiceTransportException: Not Found [404]
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:656)
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

    root cause

    org.springframework.ws.client.WebServiceTransportException: Not Found [404]
    org.springframework.ws.client.core.WebServiceTemplate.handleError(WebServiceTemplate.java:663)
    org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:587)
    org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:537)
    org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:384)
    org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:378)
    org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:370)
    com.wordpress.spring_ws2_square.HomeController.showResponse(HomeController.java:35)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    java.lang.reflect.Method.invoke(Method.java:597)
    org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
    org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426)
    org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

    note The full stack trace of the root cause is available in the VMware vFabric tc Runtime 2.7.2.RELEASE/7.0.30.A.RELEASE logs.

    ——————————————————————————–

    VMware vFabric tc Runtime 2.7.2.RELEASE/7.0.30.A.RELEASE

    Like

  2. I don’t know if it’s just me or if everyone else encountering issues with your website.
    It looks like some of the written text on your content are running off the screen.
    Can somebody else please provide feedback and let me know if this is happening to them too?
    This could be a issue with my browser because I’ve had this happen before. Cheers

    Like

  3. Hi,
    Thanks for nice tutorial !!!
    The Sprins-WS Service was executed successfully and i got getSquare.wsdl.
    But i am trying to execute the client. It was Throwing the Following Exception
    Not Found [404]
    at org.springframework.ws.client.core.WebServiceTemplate.handleError(WebServiceTemplate.java:663)
    at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:587)
    at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:537)
    at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:384)
    at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:378)
    at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:370)
    at ankeet.spring.ws2.controller.ClientController.showResponse(ClientController.java:50)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at com.springsource.insight.collection.tcserver.request.HttpRequestOperationCollectionValve.traceNextValve(HttpRequestOperationCollectionValve.java:112)
    at com.springsource.insight.collection.tcserver.request.HttpRequestOperationCollectionValve.invoke(HttpRequestOperationCollectionValve.java:94)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:279)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

    . Can u please help me. Where i done wrong !!!

    Like

    1. Hi Pavan!

      I’m not sure about the problem which’s keeping you from running the program as I’m not able to recreate the defect you mentioned. Try cleaning and debugging at your end. As many people have successfully executed this very piece of code. Try running it with mavens’s goal as I have told as the error would definitely be in your development environment.

      Follow the steps! All the best!

      Sent from an Android device

      Like

      1. Ankeet,
        I got the expected result.
        The mistake was, u had specified the Default URI for WebServiceTemplate as “http://localhost:8080/spring-ws2-exemplary/squareService”, But my VmWare was running at port: 6666. So i made the change and got it…

        Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s