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:-
- 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.
- 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.
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:
- request.jsp ย ย -> This will ask user a number whose square is to be calculated using WebService: getSquare.
- 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. ๐