Category Archives: Tutorials

JAX-WS Client: Consuming the JAX-WS webservice!

In this post we’ll see how to write a client to consume the JAX-WS webservices. This client will invoke the methods of a remote webservice. For this we’ll utilize the already created JAX-WS webservice in this post.

Since, it’s the era of webapps, our client too will be powered by Spring MVC! We can make the client in two ways, and each is simpler than the other!

Download the Client’s Source Code!

PizzaStory
This is what we’re here to do! Order Pizza! 🙂

This picture pretty much sums up the design, architecture and structure of this Producer-Consumer code!

Let’s start!

1. Download and import the PizzaService first, and get it up and running. Confirm by seeing the wsdl file at this location:

http://localhost:8080/webservice-jaxws/PizzaService?wsdl

2. Generate the artifacts using the wsimport tool. This tool will generate the required classes for you from the wsdl file. These artifacts are necessary, because now your client doesn’t know what a Pizza object looks like, and it doesn’t know which methods he can call on the remote webservice, let alone the location of it!

3. Open the command prompt and type in the following command to generate the artifacts.  Before running the command, create two folders “src” and “gen” to have the source and class files generated at different locations.

wsimport -s src -d gen http://localhost:8080/webservice-jaxws/PizzaService?wsdl

The command and its explanation!
The command and its explanation!

The directory structure to be followed is as follows:-

dir

4. Go in the “src” directory, and see the generated artifacts for yourself! I’ve included a screen-shot too! I’m so dilligent 🙂

The prized artifacts!
The prized artifacts!

5. The next thing is to copy these in your client application. I’ve written a small Spring MVC project for this purpose, and included the above classes in it. It’s hosted on Google codes and you can download it!

6. Sending the request via Ajax! We’ll write this piece of code in the form.jsp page, and on click of a button, this ajax request would be sent to the controller which in turn would call the webservices!


<script type="text/javascript">
 $(function() {

$('#invokeWebservice').click(function() {

//Sending the Ajax request, to call the JAX-WS service.
 $.ajax({
 url : '<%=request.getContextPath()%>/invokeWebservice',
 dataType: 'json',
 success: function(data){

//Setting the data in the page, for viewing!
 $('#pizzaSize').html(data.size);
 $('#pizzaCost').html(data.cost);
 $('#pizzaDateOfManufacture').html(data.dateOfManufacture);
 }
 });
 });
 });
</script>

7. Invoking the webservice can be done in two ways:-

a) Using the generated proxy classes by wsimport tool.

This is the controller. The other parts have been omitted for brevity, and only the code concerned with invoking the webservice is shown here. You can see the complete code by downloading the project! Don’t fret! 🙂

@Controller
@RequestMapping("/")
public class ClientController {

 //This gives us a proxy to the remote webservice.
 //Now call the methods on local "pizzaProxy"
 //and the remote ones will be called automatically!
 private PizzaServiceImpl pizzaProxy = new PizzaService().getPizzaPort();

//This handler will be invoked on the Ajax request.
 @RequestMapping("/invokeWebservice")
 public @ResponseBody Pizza getPizza() {
 //The webservice is being invoked by "pizzaProxy"
 //This method returns a Pizza object.
 return pizzaProxy.getPizza();
 }

}

b) Using Spring’s JaxWsPortProxyFactoryBean

For using the JaxWsPortProxyFactoryBean, you need to configure this in the Spring’s WebApplicationContext file.

<bean id="pizzaProxy" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
 <property name="serviceInterface" value="webservice.jaxws.generated.PizzaServiceImpl"/>
 <property name="wsdlDocumentUrl" value="http://localhost:8080/webservice-jaxws/PizzaService?wsdl"/>
 <property name="namespaceUri" value="generated.jaxws.webservice"/>
 <property name="serviceName" value="PizzaService"/>
 <property name="portName" value="PizzaPort"/>
 </bean>

Then autowire this in the Controller!

@Autowired
 @Qualifier("pizzaProxy")
 private PizzaServiceImpl pizzaProxy;

The directory structure of the client project is as shown below:-
projstructure
Run the the client and you’ll see the following screens.
screen1Click the button to invoke the webservice. And you’ll see the response!
screen2
That’s all for this one! Happy consuming 🙂

Git. Made simpler!

Well, by now I guess you must have heard the buzz about this cool Distributed Version Control system, if not then I suggest you use Google for a while! There are a lot of Version Control Systems hanging around in the market, and I can’t say for sure about Git’s superiority over others, mostly because I haven’t worked with others.

But one thing which I do know is that the companies and projects like Google, Facebook, Microsoft, Twitter, LinkedIn, Android, NetFlix, Qt, Eclipse and the like aren’t using Git for no reason.  And now since I too have started using Git, there’s too much to boast and extol about it. 🙂

You can download and read all the good things about Git here.

Once you download the setup, just follow the steps below and you’ll have it up and running in no time. In Windows, installation is no big deal, just a matter of next, next, and next!

Installing Git

This installs Git in your system. To see it in action, right-click and see the new options in the context menu.

Getting Git to Work

Click Git Gui and the opening screen of Git will appear.

Since we’re starting afresh we have no earlier git repositories to work with, we’ll create a brand-new-one! Click Create New Repository

Click on the “Create” button and a new repository will be created for you.

You can view the repository created for you in the Directory Structure too.

Go inside the GrandRepository to see how git saves the versions.

Now since the git is set up, let’s add some files to the project and see version control in action.

Switch to Git Gui and click Rescan button to see the new entry in the Git.

Once you click the “Rescan” button, the git will scan the directory under version control, in our case “GrandRepository” for any file changes and will show in the Git Gui

Stage the file for commit, by clicking the file in Unstaged Changes box.

Write your credentials, like name and email, so that Git will keep track of who changed the files and when.

To see the history of your project.

Make some changes in your New File.txt and do a rescan in Git Gui. You can see below the changes which you have done in the file. (Here I added a line – This is just another line.)

Commit the changes.

Go to Visualize history of all branches to see the changes and where your current branch, master is.

JAX-WS: Webservices with Java EE 6

SOAP webservices were never so much fun and ease before Java EE 6! So without further ado, we’ll see how to get a JAX-WS service up and running in a matter of minutes! The source code is hosted on Google codes, which you can download and directly import into your IDE.

(I used JBoss Developer Studio 5 and JBoss Application Server 7 )

Download the Source Code

We’ll expose a PizzaService as a JAX-WS. Our PizzaService would be a very light-weight service which will have just two functions:-

  1. getPizza – This will buy/get you a Pizza object.
  2. returnPizza – This will help you return a stale/cold/substandard Pizza back!

Let’s define Pizza entity class:-

Pizza.java

package webservice.jaxws.resources;
import java.util.Date;

public class Pizza {
 private String size;
 private Date dateOfManufacture;
 private float cost;

/*Setters and Getters removed for brevity */

}

The PizzaService Interface
PizzaService.java


package webservice.jaxws.service;

import webservice.jaxws.resources.Pizza;

public interface PizzaService {
 public Pizza getPizza();
 public String returnPizza(Pizza pizza);
}

Writing the implementation of the above interface.

PizzaServiceImpl.java


package webservice.jaxws.service;

import java.util.Date;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;

import webservice.jaxws.resources.Pizza;

@WebService(serviceName="PizzaService", portName="PizzaPort", targetNamespace="generated.jaxws.webservice")
public class PizzaServiceImpl implements PizzaService {

 @Override
 @WebMethod
 @WebResult(name="pizza")
 public Pizza getPizza() {
 //Creating a new Pizza
 Pizza pizza = new Pizza();
 pizza.setSize("Large");
 pizza.setCost(375.45f);
 pizza.setDateOfManufacture(new Date());

 return pizza;
 }

 @Override
 @WebMethod
 @WebResult(name="PizzaReturnStatus")
 public String returnPizza(@WebParam(name="pizza") Pizza pizza) {
 System.out.println("Pizza returned by the customer :(");
 System.out.println("Details of the returned pizza:-");
 System.out.println(pizza);

 return "Pizza successfully returned.";
 }

}

To expose a class as webservice all you need to do is to annotate it with @Webservice and you’re done!

The other annotations make the generated WSDL file pretty and more-meaningful to read.

  1. @WebMethod – It declares the method as an endpoint. Although the spec says it to be mandatory, but the code still runs once you annotate the service class with @WebService.
  2. @WebResult – It is used when the method is returning something, it gives the returning object a name, else your wsdl file would contain a parameter called “return” which might not seem so much readable once you have got a significant number of methods featuring in a particular webservice.
  3. @WebParam – This is also almost same as @WebResult with the only difference that this annotation is used to make the name of input argument of the endpoint more meaningful. In the absence of @WebParam, the wsdl file would read the input argument as arg0, arg1 etc.

It’s now time to put the code to test and see the output. Run the project and to see the wsdl open up your browser and type in the following url:-

http://localhost:8080/webservice-jaxws/PizzaService?wsdl

The anatomy of the above url is simple enough, http://localhost:8080/webservice-jaxws/ is the server-address and the project location and PizzaService is the service name we defined as an attribute of @WebService annotated at the class PizzaServiceImpl (scroll up to check!)

You can test the above webservice by either writing a client or using Soap-UI which is the easier and quicker way!

UPDATE

A client consuming this webservice can be seen and downloaded from this URL.

That’s all for this one.

MySQL Datasource: JNDI configuration in JBoss AS 7

This post covers the steps to configure a MySQL datasource in JBoss Application Server 7. This datasource can then be referenced via JNDI to connect your application to the underlying Database. I presume you already have a JBoss AS 7 up and running in your development environment. If not, do that first.

Download the MySQL JDBC database driver

  1. Download the latest JDBC driver for MySQL from http://dev.mysql.com/downloads/connector/j/
  2. Save the downloaded zip file and extract the connector jar.

Add the MySQL connector Driver as a Module in Server

  1. Goto: <JBoss-AS-7-Home>/modules/com
  2. Create folders mysql/main and copy the above downloaded JAR file(mysql-connector-java-5.1.21-bin.jar) in it.
  3. So your folder structure should now look like:<JBoss-AS-7-Home>/modules/com/mysql/main/mysql-connector-java-5.1.21-bin.jar
  4. Now that the Driver/Connector JAR is present, we need to define it for the Application Server.
  5. Goto: <JBoss-AS-7-Home>/modules/com/mysql/main folder where you copied the JAR file and create another file module.xml
  6. Paste the following code into it and save.
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.0" name="com.mysql">
  <resources>
    <resource-root path="mysql-connector-java-5.1.21-bin.jar"/>
  </resources>
  <dependencies>
    <module name="javax.api"/>
  </dependencies>
</module>

Since I’m using mysql-connector-java-5.1.21-bin.jar version so I’ve kept the <resource-root path = “mysql-connector-java-5.1.21-bin.jar”/>  in case you have a different version then give the same in the path attribute above, highlighted in the code-snippet.

Add the Driver reference in the Server

  1. Goto: <JBoss-AS-7-Home>/standalone/configuration/standalone.xml
  2. In the standalone.xml file add the following line in the <drivers> node.
<driver name="mysql" module="com.mysql"/>

This configures the support for a MySQL datasource in your JBoss Application server.

If you wish you can add your datasource in the standalone.xml file itself. But I prefer to keep the datasource file in my Application.

Creating the Datasource

  1. Create an xml file your-datasource.xml under your WEB-INF folder.
  2. This is a sample datasource file. my-sample-ds.xml

<?xml version="1.0" encoding="UTF-8"?>

<datasources xmlns="http://www.jboss.org/ironjacamar/schema"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.jboss.org/ironjacamar/schema http://docs.jboss.org/ironjacamar/schema/datasources_1_0.xsd">
 <!-- The datasource is bound into JNDI at this location. We reference
 this in META-INF/persistence.xml -->
 <datasource jndi-name="java:jboss/datasources/your-ds"
 pool-name="sample-pool" enabled="true"
 use-java-context="true" jta="true">
 <connection-url>jdbc:mysql://your-server-address/your-db-name</connection-url>
 <driver>mysql</driver>
 <security>
 <user-name>your-username</user-name>
 <password>your-password</password>
 </security>
 </datasource>
</datasources>

Referencing the datasource in your application

  1. Now that we have everything, we just need to refer this in our application.
  2. We can do this from persistence.xml if you’re using JPA standards.
  3. This is a sample persistence.xml which I keep under META-INF directory.

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
 xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="
 http://java.sun.com/xml/ns/persistence
 http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
 <persistence-unit name="primary">
 <provider>org.hibernate.ejb.HibernatePersistence</provider>
 <jta-data-source>java:jboss/datasources/your-ds</jta-data-source>

 <exclude-unlisted-classes>false</exclude-unlisted-classes>
 <properties>
 <!-- Properties for Hibernate -->
 <property name="hibernate.show_sql" value="true" />
 <property name="hibernate.hbm2ddl.auto" value="update" />
 <property name="hibernate.use_sql_comments" value="true" />
 <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
</properties>

</persistence-unit>

</persistence>

I used Hibernate above as my default JPA provider.

So this was all about creating and configuring a MySQL datasource in JBoss AS 7.

Aspect Oriented Programming (AOP) with Spring!

Aspect Oriented Programming complements OOP, by making the code more Object Oriented. It helps remove the unwanted parts of code from within a function or a module.

Let’s take the most mundane example of a bank transaction. Suppose you have two accounts A and B, and you want to transfer some amount (say Rs.100) from A -> B.

So your pseudo code will consist of

A = A - 100
B = B + 100.

That’s it. But is it so? Won’t you have some logging in between, if god forbids something bad happens?

So your pseudo code will now look like this,

log("Transferring Rs. 100 from A -> B")
log("Deducting from A")

A = A - 100 

log("Deducted from A")
log("Adding to B")

B = B + 100

log("Added to B")
log("Transaction completed successfully")

Did you notice all these log statements cluttering up the actual business logic?

What if, you could just skip these and still got your logging done?

What if, you could write these in a place altogether different from your business-logic-function, which could start automatically?

This is what AOP gives us. It takes away all the cross cutting concerns from the main business logic, which otherwise would look much abstruse and sometimes extraneous as well.

In AOP, there’re certain technical jargons which at first may seem confounding, but not anymore, huh!

1. Joinpoint -> They are the triggers for the Aspects to run. Joinpoint is a point during the execution of a program. It can be a method execution, or handling some exception. But, in Spring AOP the joinpoint is always a method execution.

2. Pointcut -> Pointcut is the expression or the predicate which matches a Joinpoint triggering the advice to run. It matches the joinpoint, like execution of a method, and then fires up the advice.

3. Advice -> It’s the action that takes place after a pointcut matches the joinpoint. Advice can be of different types, “After”, “Around”, Before” etc. The advice contains the code which we want to execute on the execution of our business logic.

So let’s get our hands dirty with  coding. We’ll make a quite simple sample app.

You don’t have to copy paste, the source code is hosted on Google Codes.

Download Source Code.

1. Create the project directory structure

Type the below command in the command prompt in one line:

mvn archetype:create -DgroupId=ankeet.spring.aop -DartifactId=spring-aop-sample

Now navigate to the the project directory and execute the following command, to import the project to STS/Eclipse. Or, you can import as Existing Maven Projects too.

mvn eclipse:eclipse

Import now into STS/Eclipse as existing projects.

Delete the test folders and the App.java as shown above.

Add a new source folder named src/main/resources. 

Your directory structure should now look like this.

2. Create two packages in the src/main/java folder:

ankeet.spring.business –> This will contain the business logic which we want to be pure business, ankeet.spring.tester –> It’ll contain the main() to run the program. And we already have a package ankeet.spring.aop –> which will contain the AOP aspect, and will get triggered when the business logic will run.

So we will have the AOP code separated from business logic.

2. In the ankeet.spring.business package create a new class 

BusinessLogic.java

package ankeet.spring.business;

public class BusinessLogic {
	public void iDontKnowAboutAspects() {
		System.out.println("Start of function.");
		System.out.println("This is a Dummy function.");
		System.out.println("End of function.");
	}
}

3. In the ankeet.spring.aop package create a new class

AOPAspect.java

/**
 *
 */
package ankeet.spring.aop;

import java.util.Arrays;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
/**
 * @author ankeet
 *
 */
@Aspect
public class AOPAspect {

 @Pointcut("execution(* *.*(..))")
 public void aspectOperations(){}

 @Before("aspectOperations()")
 public void before(JoinPoint joinPoint) {
 System.out.println();
 System.out.println("#######################Before Advice START########################");
 System.out.println("The method ->" + joinPoint.getSignature().getName() + "() begins.");
 System.out.println("The details of the method are as follows:-");
 System.out.println("Method kind : " + joinPoint.getKind());
 System.out.println("Signature declaring type : " + joinPoint.getSignature().getDeclaringTypeName());
 System.out.println("Signature name : " + joinPoint.getSignature().getName());
 System.out.println("Arguments : " + Arrays.toString(joinPoint.getArgs()));
 System.out.println("Target class : " + joinPoint.getTarget().getClass().getName());
 System.out.println("This class : " + joinPoint.getThis().getClass().getName());
 System.out.println("########################Before Advice END#########################");
 System.out.println();
 }

 @After("aspectOperations()")
 public void after(JoinPoint joinPoint) {
 System.out.println();
 System.out.println("#######################After Advice START########################");
 System.out.println("The method ->" + joinPoint.getSignature().getName() + "() ends.");
 System.out.println("The details of the method are as follows:-");
 System.out.println("Method kind : " + joinPoint.getKind());
 System.out.println("Signature declaring type : " + joinPoint.getSignature().getDeclaringTypeName());
 System.out.println("Signature name : " + joinPoint.getSignature().getName());
 System.out.println("Arguments : " + Arrays.toString(joinPoint.getArgs()));
 System.out.println("Target class : " + joinPoint.getTarget().getClass().getName());
 System.out.println("This class : " + joinPoint.getThis().getClass().getName());
 System.out.println("########################After Advice END########################");
 System.out.println();
 }
}

This aspect basically consists of a lot of System.out.println() statements to show the details of the method which it can access. So don’tget confused with all these println-s cluttering up!
4. Now write the main method to test our application.

Tester.java


/**
 *
 */
package ankeet.spring.tester;

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

import ankeet.spring.business.BusinessLogic;
/**
 * @author ankeet
 *
 */
public class Tester {

 public static void main(String[] args) {
 //Loading "AOP.xml"
 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("AOP.xml");
 //Getting bean from the application context.
 BusinessLogic businessLogic = (BusinessLogic) applicationContext.getBean("businessLogic");
 //Calling the function -> iDontKnowAboutAspects()
 businessLogic.iDontKnowAboutAspects();
 }
}

6. Now write the bean file AOP.xml, and put it into the src/main/resources folder.


<?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:p="http://www.springframework.org/schema/p"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xsi:schemaLocation="
 http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans.xsd
 http://www.springframework.org/schema/aop
 http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
 <aop:aspectj-autoproxy />

 <bean id="businessLogic" class="ankeet.spring.business.BusinessLogic"/>
 <bean id="aOPAspect" class="ankeet.spring.aop.AOPAspect"/>

</beans>

This file declares the beans for the Container, so that it can instantiate when you ask for them, that’s what IoC, and DI are all about!

7. So, we’re all done except for declaring the dependencies. So, there we go, our POM file.

pom.xml


<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>ankeet.spring.aop</groupId>
 <artifactId>spring-aop-sample</artifactId>
 <version>1.0-SNAPSHOT</version>
 <packaging>jar</packaging>
 <name>spring-aop-sample</name>
 <url>http://maven.apache.org</url>
 <properties>
 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 </properties>
 <dependencies>
 <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-context</artifactId>
 <version>3.1.0.RELEASE</version>
 </dependency>
 <dependency>
 <groupId>cglib</groupId>
 <artifactId>cglib-nodep</artifactId>
 <version>2.2.2</version>
 </dependency>
 <dependency>
 <groupId>org.aspectj</groupId>
 <artifactId>aspectjweaver</artifactId>
 <version>1.6.12</version>
 </dependency>
 <dependency>
 <groupId>org.aspectj</groupId>
 <artifactId>aspectjrt</artifactId>
 <version>1.6.12</version>
 </dependency>
 <dependency>
 <groupId>junit</groupId>
 <artifactId>junit</artifactId>
 <version>3.8.1</version>
 <scope>test</scope>
 </dependency>
 </dependencies>
</project>

Your final directory structure should look like this.

The output of the application in the console looks like this!

So, this is all, just download the project and run the Tester.java as Java Application, and you can see the output.

That’s all folks for this post, have fun!

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. 🙂

Spring Web Services 2. Made easy!

We’ll see how to develop Spring Webservices 2, along with validation on the base of xml schema. We’ll use spring-ws 2, maven, jaxb for making this sample project spring-ws2-exemplary. 

Source Code!

You don’t need to copy paste the code, it’s available for download at the bottom of the page. The project may give some errors while building due to non-conformance of Maven 3, so for that I’ve enhanced the POM and you can download the new project from here.

We’ll see the whole process in easy steps, making no big dragon of this!

1. I presume you are probably aware of maven. Setting it up is easy. If you’re not a maven-compatriot, don’t worry, google it, and you’ll have it up and running in a matter of mins.

So all said and done, lets start the development rightaway.

2. Open command prompt and navigate to your workspace location, or wherever you need to make the project.

3. Type in the following command, all in one line.

mvn archetype:create -DarchetypeGroupId=org.springframework.ws -DarchetypeArtifactId=spring-ws-archetype -DarchetypeVersion=2.0.1.RELEASE -DgroupId=ankeet.spring.ws2 -DartifactId=spring-ws2-exemplary

So there you have the basic skeleton of the project ready for you, including the spring config files, pom.xml and the requisite folder structure. Go have look 😉

4. Now you have the basic structure with you, but it still doesn’t qualifies to be imported as a project in eclipse or SpringsourceToolSuite (STS), as it lacks the .classpath and .project files.

To overcome, go to the project folder spring-ws2-exemplary in this case and run the following command:-

mvn eclipse:eclipse

Now you can import this as Existing Projects into Workspace

5. Creating the xml request and response messages. We’ll create a service SquareService, which will give the square of the input number.

So our request will be

        <SquareServiceRequest>
	   <Input>3</Input>
	</SquareServiceRequest>

and response will be

       <SquareServiceResponse>
	  <Output>9</Output>
       </SquareServiceResponse>

6. Since, you now have the request and response messages combine it into one xml file and generate the xsd.

Combining the request and response in a file spring-ws2-square.xml

<?xml version="1.0" encoding="UTF-8"?>
<SquareService xmlns="https://ankeetmaini.wordpress.com/spring-ws2-square">

	<SquareServiceRequest>
		<Input>3</Input>
	</SquareServiceRequest>

	<SquareServiceResponse>
		<Output>9</Output>
	</SquareServiceResponse>

</SquareService>

7. To generate the xsd, you can use trang.jar if you don’t have anything else. Its an open source product.

Download the latest version and unzip it on your system. Open command prompt and navigate to the unzipped folder.

To create the XSD run the following command:

java -jar trang.java <Path-of-XML-file> <Path-where-xsd-is-to-be-generated>

I copied my xml to the trang direcotory only, and generated my corresponding xsd there too, and then copied it to WEB-INF. Simple.

So you have the xsd generated in the current directory. Before putting it into use, we need to tweak it a little bit to suit our purposes.

Original spring-ws2-square.xsd


<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="https://ankeetmaini.wordpress.com/spring-ws2-square" xmlns:s="https://ankeetmaini.wordpress.com/spring-ws2-square">
  <xs:element name="SquareService">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="s:SquareServiceRequest"/>
        <xs:element ref="s:SquareServiceResponse"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="SquareServiceRequest">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="s:Input"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="Input" type="xs:integer"/>
  <xs:element name="SquareServiceResponse">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="s:Output"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="Output" type="xs:integer"/>
</xs:schema></pre>

Editing it, we get the final xsd. Please note the finer details yourself, and try to comprehend. You’ll be able to figure out the need to edit it most of the times for the sake of more conciseness, and removal of extraneous elements, if you know what I mean 😉

Final spring-ws2-square.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="https://ankeetmaini.wordpress.com/spring-ws2-square" xmlns:s="https://ankeetmaini.wordpress.com/spring-ws2-square">

  <xs:element name="SquareServiceRequest">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Input" type="xs:integer"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name="SquareServiceResponse">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Output" type="xs:integer"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

</xs:schema>

Now copy this to the src/main/webapp/WEB-INF folder, so that it’ll be detected at classpath.

8. Open web.xml located in WEB-INF folder and change the name of the servlet to spring-ws2 (This is not required but I do, to remove the ambiguity, if at all it arises). Don’t forget to change in the <servlet-maping> also.

Add an init param

<init-param>
			<param-name>transformWsdlLocations</param-name>
			<param-value>true</param-value>
		</init-param>

Verify your web.xml looks like this:-

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
         version="2.4">

    <display-name>Archetype Created Web Application</display-name>

 	<servlet>
		<servlet-name>spring-ws2</servlet-name>
		<servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet
		</servlet-class>
		<init-param>
			<param-name>transformWsdlLocations</param-name>
			<param-value>true</param-value>
		</init-param>
	</servlet>

    <servlet-mapping>
        <servlet-name>spring-ws2</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

</web-app>

9. Now, since you changed the servlet’s name, you need to change the Spring’s configuration file too, because the container will look for <servlet-name>-servlet.xml

Rename (or better Refactor) it to spring-ws2-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:sws="http://www.springframework.org/schema/web-services"
       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.xsd
       http://www.springframework.org/schema/web-services                      	http://www.springframework.org/schema/web-services/web-services-2.0.xsd">

    <!-- To detect @Endpoint -->
<sws:annotation-driven/>

<!-- To detect @Service, @Component etc -->
<context:component-scan base-package="ankeet.spring" />

    <!-- To generate dynamic wsdl -->
	<sws:dynamic-wsdl
		id="getSquare"
		portTypeName="SquareService"
		locationUri="/squareService"
		targetNamespace="https://ankeetmaini.wordpress.com/spring-ws2-square">
		<sws:xsd location="/WEB-INF/spring-ws2-square.xsd"/>
	</sws:dynamic-wsdl>

    <!-- For validating your request and response -->
    <!-- So that you don't send a string instead of an integer -->

	 <sws:interceptors>
<bean id="validatingInterceptor"
        class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor">
    <property name="schema" value="/WEB-INF/spring-ws2-square.xsd"/>
    <property name="validateRequest" value="true"/>
    <property name="validateResponse" value="true"/>
</bean>
  </sws:interceptors>

</beans>

10. In Eclipse/STS right click your project and and then new, and select a new source folder and name it as src/main/java

Create three packages : ankeet.spring.ws2.endpoint, ankeet.spring.ws2.service, ankeet.spring.ws2.generated

11. Since we’re using jaxb for converting xml <—> object, we need to make changes to the pom.xml to add its dependencies and plugins, so that the Java Classes are generated at compile time from the XSD given.

Add the following piece of code to the pom in the <plugins> section

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>jaxb2-maven-plugin</artifactId>
  <executions>
    <execution>
      <goals>
	<goal>xjc</goal>
      </goals>
     </execution>
   </executions>
  <configuration>
    <schemaDirectory>src/main/webapp/WEB-INF/</schemaDirectory>
  </configuration>
</plugin>

Similarly add the dependencies in the <dependencies> section of POM.

<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>4.8.1</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>log4j</groupId>
  <artifactId>log4j</artifactId>
  <scope>compile</scope>
  <version>1.2.16</version>
</dependency>

11. Write the endpoint class as follows:-

SquareWSEndpoint.java

/**
 *
 */
package ankeet.spring.ws2.endpoint;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ws.server.endpoint.annotation.Endpoint;
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
import org.springframework.ws.server.endpoint.annotation.RequestPayload;
import org.springframework.ws.server.endpoint.annotation.ResponsePayload;

import ankeet.spring.ws2.generated.*;
import ankeet.spring.ws2.generated.SquareServiceResponse;
import ankeet.spring.ws2.service.SquareService;

/**
 * @author Ankeet Maini
 *
 */
@Endpoint
public class SquareWSEndpoint {
	//To calculate square of the input.
	@Autowired
	private SquareService squareService;
	//This is like @RequestMapping of Spring MVC
	@PayloadRoot(localPart="SquareServiceRequest", namespace="https://ankeetmaini.wordpress.com/spring-ws2-square")
	@ResponsePayload
	public SquareServiceResponse getSquare(@RequestPayload SquareServiceRequest request) {
		SquareServiceResponse response = new ObjectFactory().createSquareServiceResponse();
		response.setOutput(squareService.square(request.getInput()));
		return response;
	}
}

12. Now write the service classes which will actually do the squaring.

SquareService.java

package ankeet.spring.ws2.service;

import java.math.BigInteger;

public interface SquareService {
	public BigInteger square(BigInteger bigInteger);

}

And it’s implementation class SquareServiceImpl.java

package ankeet.spring.ws2.service;

import java.math.BigInteger;

import org.springframework.stereotype.Service;

@Service
public class SquareServiceImpl implements SquareService {

	public BigInteger square(BigInteger bigInteger) {
		return (bigInteger.multiply(bigInteger));
	}

}

13. Now when you clean your project JAXB will create the classes from the XSD present on the classpath, in our case spring-ws2-square.xsd located in WEB-INF. The code generated will be in the target folder, so you’ll have to copy the files and put into the ankeet.spring.ws2.generated package, and correct the inconsistencies arising in the package names by shifting. Also, make src/main/webapp a source folder(By navigating to webapp and then right clicking and in Configure Buildpath, make it a source folder).

14. After this your project structure should prcisely look like this.

15. To run the project you can create a war and deploy on the server, or use maven. Go the project directory and type the following command to run the project on tomcat server:

mvn tomcat:run

16. Open your web browser and enter the following url

http://localhost:8080/spring-ws2-exemplary/getSquare.wsdl to see the WSDL file generated.

17. To test the application, you can build a client or use Soap UI. To test with soap UI, open it, create an new project and give it the above url of WSDL.

Press Ok.

Click on Request1 and on the left side an interface will appear asking your request. Enter any integer and press the green button to send it to the server. If you enter anything other than an integer, a Validation error will be reported on the other side.

and if you do enter any thing else than integer, say a string, the Validation will fail and you’ll get the following error.

Just in case if you wish to know, the above Response is

<pre><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header/>
   <SOAP-ENV:Body>
      <SOAP-ENV:Fault>
         <faultcode>SOAP-ENV:Client</faultcode>
         <faultstring xml:lang="en">Validation error</faultstring>
         <detail>
            <spring-ws:ValidationError xmlns:spring-ws="http://springframework.org/spring-ws">cvc-datatype-valid.1.2.1: 'a' is not a valid value for 'integer'.</spring-ws:ValidationError>
            <spring-ws:ValidationError xmlns:spring-ws="http://springframework.org/spring-ws">cvc-type.3.1.3: The value 'a' of element 'spr:Input' is not valid.</spring-ws:ValidationError>
         </detail>
      </SOAP-ENV:Fault>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

The code is hosted on Google Codes, to download the project click here.

To run it, just unzip the file, open command prompt, navigate to the directory and type : mvn tomcat:run, and voila you’re done!

While creating this project I read a lot, and found these blogs extremely helpful,

1. Jamesbnuzzo

2. Ice09

3. krams

That’s all for this one. Enjoy building and running it. 🙂

JMS, Spring’s Way!

With JMS, different applications can communicate in a very loosely coupled way when compared to other remoting technologies like RMI. But, when you use JMS API to send/recieve messages, you have to manage JMS resources yourself, along with handling JMS Exceptions, which result into a lot of JMS code cluttering in your application.

Spring greatly simplifies the task by providing a template-based solution. All the resources are taken care of, by yes, you guessed it: Spring’s Container, and its IOC container listens for messages and even reacts to them for you! Nonetheless Spring also converts its exception hierarchy into a set of unchecked exceptions.

Diving right into the code!

We’ll create an interface for sending a message, of course JMS Message. We’ll send an object, say Book as message.

Creating an interface for sending book.

BookSender.java

/**
 *
 */
package ankeet.spring.sender;

import ankeet.spring.model.Book;

/**
 * @author Ankeet Maini
 *
 */
public interface BookSender {

	public void sendBook(Book book);

}

Writing an implementation class for it.

BookSenderImpl.java

/**
 *
 */
package ankeet.spring.sender;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import ankeet.spring.model.Book;

/**
 * @author Ankeet Maini
 *
 */
@Component
public class BookSenderImpl implements BookSender {
	@Autowired
	private JmsTemplate jmsTemplate;

	public JmsTemplate getJmsTemplate() {
		return jmsTemplate;
	}

	public void setJmsTemplate(JmsTemplate jmsTemplate) {
		this.jmsTemplate = jmsTemplate;
	}

	@Override
	@Transactional
	public void sendBook(Book book) {
		System.out.println("Sending JMS Message -> Book");
		System.out.println(book);

		jmsTemplate.convertAndSend(book);

		System.out.println("Book sent.");
	}
}

JmsTemplate

  • Given by Spring to make life easy.
  • Facilitates sending, converting, getting session etc.
  • In a nut shell it is one-stop-shop for JMS activities.

Creating a JMS listener for the above sender.

BookReceiverImpl.java

/**
 *
 */
package ankeet.spring.receiver;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import ankeet.spring.model.Book;

/**
 * @author Ankeet Maini
 *
 */
@Component
public class BookReceiverImpl implements MessageListener{

	@Autowired
	private Book book;

	@Autowired
	private JmsTemplate jmsTemplate;

	public JmsTemplate getJmsTemplate() {
		return jmsTemplate;
	}

	public void setJmsTemplate(JmsTemplate jmsTemplate) {
		this.jmsTemplate = jmsTemplate;
	}

	@Transactional
	@Override
	public void onMessage(Message message) {
		System.out.println("Receiver invoked...");
		System.out.println("In onMessage()");
		System.out.println("Printing JMS Message Details ->"+message);
		System.out.println("Converting to object message...");

		ObjectMessage objectMessage = (ObjectMessage) message;

		System.out.println("Printing downcasted Object Message Details ->" + objectMessage);

		System.out.println("Downcasting ObjectMessage to Book...");
		try {
			book = (Book) objectMessage.getObject();
		} catch (JMSException e) {
			e.printStackTrace();
		}

		System.out.println("Going out of onMessage()");
		System.out.println("Going out of Receiver...Bye");
	}
}

Here @Transactional is used to maintain a transaction of sending and receiving messages.

onMessage() is the default listener method, although we can resort to some other by defining a MessageListenerAdapter.

The message – Book is defined below.

Book.java

/**
 *
 */
package ankeet.spring.model;

import java.io.Serializable;

import javax.validation.constraints.Digits;
import javax.validation.constraints.Size;

import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.stereotype.Component;

/**
 * @author Ankeet Maini
 *
 */
@Component
public class Book implements Serializable {

	private static final long serialVersionUID = 1L;

	@NotEmpty
	private String name;

	@Digits(fraction = 0, integer = 3)
	private int price;

	@NotEmpty
	private String author;

	@Size(min=2, max=20)
	@Email
	private String email;

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getPrice() {
		return price;
	}
	public void setPrice(int price) {
		this.price = price;
	}
	public String getAuthor() {
		return author;
	}
	public void setAuthor(String author) {
		this.author = author;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getEmail() {
		return email;
	}
	@Override
	public String toString() {
		System.out.println("Book Details-> Name: " + this.getName() + " || Author: " + this.getAuthor() + " || Price: " +  this.getPrice() + " || Email: " + this.getEmail());
		return super.toString();
	}
}

Writing the controller for the app, which on its invocation, fires up a JSP page asking you to fill in the details of a Book, then sends this object as JMS message, which in turn is caught by the diligent listener we have written.

FrontController.java

package ankeet.spring.controller;

import java.util.Set;


import javax.validation.ConstraintViolation;
import javax.validation.Validator;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import ankeet.spring.model.Book;
import ankeet.spring.sender.BookSender;

/**
 * @author Ankeet Maini
 *
 */
@Controller
@RequestMapping("view")
public class FrontController {

	@Autowired
	private Validator validator;

	@Autowired
	private BookSender bookSender;

	@RequestMapping
	public String showForm(Model model) {
		model.addAttribute("book", new Book());
		return "form";
	}

	@RequestMapping(params="submitBook")
	public String submitForm(@ModelAttribute("book") Book book, BindingResult bindingResult, Model model) {

		//creating a Set of "ConstraintViolation" of type Book and validating using javax.validation.Validator
		Set<ConstraintViolation<Book>> constraintViolations = validator.validate(book);

		//All the violations are now stored in "constraintViolations"
		//Taking each violation and extracting the property on which violation was registered along
		//with the violation error message.
		//Finally adding the violation as errors in BindingResult.

		for(ConstraintViolation<Book> constraintViolation : constraintViolations) {
			String propertyPath = constraintViolation.getPropertyPath().toString();
			String message = constraintViolation.getMessage();
			bindingResult.addError(new FieldError("member", propertyPath, "Invalid " + propertyPath + "->" + message));
		}

		//If there are any errors, send back to the form again, to be displayed to user.
		if(!bindingResult.hasErrors()) {
			bookSender.sendBook(book);
		}
		return "form";
	}
}

The jsp page and all the configuration files…

form.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="portlet" uri="http://java.sun.com/portlet_2_0"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
	<head></head>
	<body>
	<portlet:renderURL var="go"></portlet:renderURL>
		<form:form method="post" commandName="book" action="${go}">
			<table>
				<tr>
					<td>Name:</td><td><form:input path="name" /></td>
					<td><font color="red"><form:errors path="name" /></font></td>
				</tr>
				<tr>
					<td>Price:</td><td><form:input path="price"/></td>
					<td><font color="red"><form:errors path="price" /></font></td>
				</tr>
				<tr>
					<td>Author:</td><td><form:input path="author"/></td>
					<td><font color="red"><form:errors path="author" /></font></td>
				</tr>
				<tr>
					<td>Email:</td><td><form:input path="email"/></td>
					<td><font color="red"><form:errors path="email" /></font></td>
				</tr>
				</table>
				<input name="submitBook" type="submit" value="Create"  />
		</form:form>
	</body>
</html>

SpringJMS-portlet.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:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:util="http://www.springframework.org/schema/util"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/util
        http://www.springframework.org/schema/util/spring-util.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
        ">
	<context:component-scan base-package="ankeet.spring" />
	<mvc:annotation-driven />
	<tx:annotation-driven />

	<!-- For JMS Transaction -->

	<bean id="transactionManager"
        class="org.springframework.jms.connection.JmsTransactionManager">
        <property name="connectionFactory">
            <ref bean="connectionFactory" />
        </property>
    </bean>

	<!-- JMS Destination -->

	<bean id="destination" class="org.activemq.message.ActiveMQQueue">
		<constructor-arg value="queue" />
	</bean>

	<!-- JmsTemplate -->

	<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
		<property name="connectionFactory" ref="connectionFactory" />
		<property name="defaultDestination" ref="destination" />
	</bean>

	<!-- Connection Factory -->

	<bean id="connectionFactory" class="org.activemq.ActiveMQConnectionFactory">
			<property name="brokerURL" value="vm://localhost" />
	</bean>
	<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
		<property name="connectionFactory" ref="connectionFactory" />
		<property name="destination" ref="destination" />
		<property name="messageListener" ref="bookReceiverImpl"/>
		 </bean>

		 <!-- View Resolver -->

	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/views/" />
		<property name="suffix" value=".jsp" />
	</bean>
</beans> 

Running the project and gauging the functionality:-

When the project runs, a JSP would be shown asking book details, when you enter and submit, it will be sent as JMS ObjectMessage and received by BookReceiverImpl and the output will be displayed in Console.

I’ve used Apache ActiveMQ as message Broker, which is an open source message broker.

Screen-shots!

1. Eclipse Directory Structure

Eclipse directory structure2. Required Jars

3. First Screen

4. Fill in the Book details

5. Submit and see the console.

6. The following is the console log, if you wish to see.

[10/13/11 11:07:30:623 IST] 00000245 BrokerContain I org.activemq.broker.impl.BrokerContainerImpl registerConnection Adding new client: ID:HPWKS-21-51889-1318484241311-11:0 on transport: VmTransportChannel: null
[10/13/11 11:07:30:623 IST] 00000245 SystemOut     O Book Details-> Name: Revolution 2020 || Author: Chetan Bhagat || Price: 140 || Email: chetanbhagat@gmail.com
[10/13/11 11:07:30:643 IST] 00000245 BrokerContain I org.activemq.broker.impl.BrokerContainerImpl deregisterConnection Removing client: ID:HPWKS-21-51889-1318484241311-11:0 on transport: VmTransportChannel: null
[10/13/11 11:07:30:643 IST] 0000057c SystemOut     O Book Details-> Name: Revolution 2020 || Author: Chetan Bhagat || Price: 140 || Email: chetanbhagat@gmail.com
[10/13/11 11:07:30:643 IST] 0000057c SystemOut     O Printing JMS Message Details ->ACTIVEMQ_OBJECT_MESSAGE: id = 3 ActiveMQMessage{ , jmsMessageID = ID:HPWKS-21-51889-1318484241311-17:0, bodyAsBytes = org.activemq.io.util.ByteArray@46214621, readOnlyMessage = true, jmsClientID = 'ID:HPWKS-21-51889-1318484241311-11:0' , jmsCorrelationID = 'null' , jmsDestination = queue, jmsReplyTo = null, jmsDeliveryMode = 2, jmsRedelivered = false, jmsType = 'null' , jmsExpiration = 0, jmsPriority = 4, jmsTimestamp = 1318484250633, properties = null, readOnlyProperties = true, entryBrokerName = 'ID:HPWKS-21-51889-1318484241311-0:0' , entryClusterName = 'default' , consumerNos = [0], transactionId = 'ID:HPWKS-21-51889-1318484241311-15:0' , xaTransacted = false, consumerIdentifer = 'ID:HPWKS-21-51889-1318484241311-4:0.1.1' , messageConsumed = false, transientConsumed = false, sequenceNumber = 0, deliveryCount = 1, dispatchedFromDLQ = false, messageAcknowledge = org.activemq.ActiveMQSession@30f230f2, jmsMessageIdentity = org.activemq.service.MessageIdentity@7467e559[id=ID:HPWKS-21-51889-1318484241311-17:0; sequenceNo=null], producerKey = ID:HPWKS-21-51889-1318484241311-17: } ActiveMQObjectMessage{ object = ankeet.spring.model.Book@3e273e27 }
[10/13/11 11:07:30:643 IST] 0000057c SystemOut     O Book Details-> Name: Revolution 2020 || Author: Chetan Bhagat || Price: 140 || Email: chetanbhagat@gmail.com
[10/13/11 11:07:30:643 IST] 0000057c SystemOut     O Printing downcasted Object Message Details ->ACTIVEMQ_OBJECT_MESSAGE: id = 3 ActiveMQMessage{ , jmsMessageID = ID:HPWKS-21-51889-1318484241311-17:0, bodyAsBytes = org.activemq.io.util.ByteArray@46214621, readOnlyMessage = true, jmsClientID = 'ID:HPWKS-21-51889-1318484241311-11:0' , jmsCorrelationID = 'null' , jmsDestination = queue, jmsReplyTo = null, jmsDeliveryMode = 2, jmsRedelivered = false, jmsType = 'null' , jmsExpiration = 0, jmsPriority = 4, jmsTimestamp = 1318484250633, properties = null, readOnlyProperties = true, entryBrokerName = 'ID:HPWKS-21-51889-1318484241311-0:0' , entryClusterName = 'default' , consumerNos = [0], transactionId = 'ID:HPWKS-21-51889-1318484241311-15:0' , xaTransacted = false, consumerIdentifer = 'ID:HPWKS-21-51889-1318484241311-4:0.1.1' , messageConsumed = false, transientConsumed = false, sequenceNumber = 0, deliveryCount = 1, dispatchedFromDLQ = false, messageAcknowledge = org.activemq.ActiveMQSession@30f230f2, jmsMessageIdentity = org.activemq.service.MessageIdentity@7467e559[id=ID:HPWKS-21-51889-1318484241311-17:0; sequenceNo=null], producerKey = ID:HPWKS-21-51889-1318484241311-17: } ActiveMQObjectMessage{ object = ankeet.spring.model.Book@3e273e27 }
[10/13/11 11:07:30:623 IST] 00000245 SystemErr     R Sending JMS Message -> Book
[10/13/11 11:07:30:623 IST] 00000245 SystemErr     R Object which we're sending ->ankeet.spring.model.Book@29142914
[10/13/11 11:07:30:633 IST] 00000245 SystemErr     R Book sent.
[10/13/11 11:07:30:643 IST] 0000057c SystemErr     R Receiver invoked...
[10/13/11 11:07:30:643 IST] 0000057c SystemErr     R In onMessage()
[10/13/11 11:07:30:643 IST] 0000057c SystemErr     R Converting to object message...
[10/13/11 11:07:30:643 IST] 0000057c SystemErr     R Downcasting ObjectMessage to Book...
[10/13/11 11:07:30:643 IST] 0000057c SystemErr     R Going out of onMessage()
[10/13/11 11:07:30:643 IST] 0000057c SystemErr     R Going out of Receiver...Bye

That’s it. Enjoy!

Web Apps with Spring Portlet MVC!

UPDATE

A sample JSR 286 Portlet project has been uploaded to support this blog post on the request of readers. You can download the source code which is hosted at Google Codes.

P.S. There may be minor changes in the code which is explained in the post and the one available for download, but it won’t amount to any ambiguities concept wise, just some naming changes!

Download Source Code

Introduction to Portlets!

A Portlet is nothing but a servlet like component, designed to handle requests and give back responses. Spring 3 supports portlet version 2.0, covered under the JSR 286 specification.

The central component in Portlet is the DispatcherPortlet which is the primary component that caters to all the requests coming in, and then selects an appropriate handler to handle them.

The basic block diagram of the DispatcherPortlet and its role in MVC architecture catering to requests and generating responses is shown below.

Spring Portlet MVC

Lets get straight to code!

Create a new Portlet Project -> “SpringPortletExemplary” as you’ll see its exemplary in more ways than one. 😉

I use IBM’s Rational Application Developer (RAD), thanks to my Company!

First write the web.xml – The Deployment Descripter of the App

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
	<display-name>SpringPortletExemplary</display-name>
	<listener>
		<description>
		</description>
		<display-name>ContextLoaderListener</display-name>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<servlet>
		<description>
		</description>
		<display-name>View</display-name>
		<servlet-name>View</servlet-name>
		<servlet-class>
		org.springframework.web.servlet.ViewRendererServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>View</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
</web-app>

After it write the portlet.xml – which tells us the main portlet’s name which is org.springframework.web.portlet.DispatcherPortlet and for what all modes its operational, as such there are three modes “view”, “edit” and “help”, but for simplicity’s sake we’ll configure for “view” mode only.

<?xml version="1.0" encoding="UTF-8"?>
<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" id="ankeet.spring.portlet.SpringPortletExemplaryPortlet.679853d803">
	<portlet>
		<portlet-name>SpringPortletExemplary</portlet-name>
		<display-name xml:lang="en">SpringPortletExemplary</display-name>
		<display-name>SpringPortletExemplary</display-name>
		<portlet-class>org.springframework.web.portlet.DispatcherPortlet</portlet-class>
		<expiration-cache>0</expiration-cache>
		<supports>
			<mime-type>text/html</mime-type>
			<portlet-mode>view</portlet-mode>
		</supports>
		<supported-locale>en</supported-locale>

		<portlet-info>
			<title>SpringPortletExemplary</title>
			<short-title>SpringPortletExemplary</short-title>
			<keywords>SpringPortletExemplary</keywords>
		</portlet-info>
	</portlet>
	<default-namespace>http://SpringPortletExemplary/</default-namespace>
</portlet-app>

Since the name of our portlet is SpringPortletExemplary, the Container will search for <portlet-name>-portlet.xml, so in our case SpringPortletExemplary-portlet.xml, so writing it rightaway…

<?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:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:util="http://www.springframework.org/schema/util"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/util
        http://www.springframework.org/schema/util/spring-util.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
        ">

<!-- Scans the classpath of this application for @Components to deploy as beans -->
	<context:component-scan base-package="ankeet.spring" />
<!-- Configures the @Controller programming model -->
	<mvc:annotation-driven />

     <!-- To declare Controller bean - Is it mandatory or not yet to be seen. -->
     <!-- Resolves view names to protected .jsp resources within the /WEB-INF/views directory -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/views/"/>
		<property name="suffix" value=".jsp"/>
	</bean>
</beans>

Thus, declaring the InternalViewResourceResolver to determine the view name, and enabling component scan to detect annotations like @Component, @Controller and @RequestMapping, as we’ll employ the practices encouraged by Spring 3!

Now since in our web.xml we specified ContextLoaderListener which will load the root application context at startup, thus writing applicationContext.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:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:util="http://www.springframework.org/schema/util"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/util
        http://www.springframework.org/schema/util/spring-util.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
        ">

    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
		<property name="basename" value="/WEB-INF/messages" />
	</bean>
</beans>

So just declared a MessageSource bean, which is responsible for giving customized error messages, which you’ll see later.
Create all these files in WEB-INF directory.
Now, creating the source files. We’ll develop an application which asks user to enter details of a book, and upon validating the same we’ll display the result in another JSP page.
We’ll use Spring’s Object binding support, and for validation JSR-303 and Hibernate Validator, which are the most sought after today.
JSR-303 validations are accomplished by decorating the Data class with annotations which you’ll see in a short time.
These JSR-303 validations are declarative instead of configurative as was the case with Apache Commons and Spring’s in-built Validator, which used XML file and POJO to specify the constraints.
But, now all that’s gone for a toss, as new and slick annotations have taken centre stage, making the code cleaner and sleeker!
Book.java

/**
 *
 */
package ankeet.spring.model;

import javax.validation.constraints.Digits;
import javax.validation.constraints.Size;

import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.stereotype.Component;

/**
 * @author ankeet
 *
 */
@Component
public class Book {
	@NotEmpty(message="NotEmpty.book.name")
	private String name;

	@Digits(fraction = 0, integer = 3)
	private int price;

	@NotEmpty(message="NotEmpty.book.author")
	private String author;

	@NotEmpty(message="NotEmpty.book.email")
	@Email(message="Email.book.email")
	private String email;

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getPrice() {
		return price;
	}
	public void setPrice(int price) {
		this.price = price;
	}
	public String getAuthor() {
		return author;
	}
	public void setAuthor(String author) {
		this.author = author;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getEmail() {
		return email;
	}
}

Now writing the Controller Class, we have, FrontController.java

package ankeet.spring.controller;

import java.util.Locale;
import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.Validator;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import ankeet.spring.model.Book;

/**
 * @author Ankeet Maini
 *
 */
@Controller
@RequestMapping("view")
public class FrontController {

	@Autowired
	MessageSource messageSource;

	@Autowired
	Book book;

	@Autowired
	private Validator validator;

	@RequestMapping
	public String showForm(Model model) {
		model.addAttribute("book", book);
		return "form";
	}

	@RequestMapping(params="submitBook")
	public String submitForm(@ModelAttribute("book") Book book, BindingResult bindingResult, Model model) {

		//creating a Set of "ConstraintViolation" of type Book and validating using javax.validation.Validator
		Set<ConstraintViolation<Book>> constraintViolations = validator.validate(book);
		//All the violations are now stored in "constraintViolations"
		//Taking each violation and extracting the property on which violation was registered along
		//with the violation error message.
		//Finally adding the violation as errors in BindingResult.
		for(ConstraintViolation<Book> constraintViolation : constraintViolations) {
			String propertyPath = constraintViolation.getPropertyPath().toString();
			String message = constraintViolation.getMessage();
			bindingResult.addError(new FieldError("member", propertyPath, messageSource.getMessage(message, null, message, null)));
		}

		//If there are any errors, send back to the form again, to be displayed to user.
		if(!bindingResult.hasErrors()) {
			model.addAttribute("submittedBook", book);
			return "success";
		}
		return "form";
	}
}


Thus the FrontController first gives you “form.jsp” to fill in the details and when you submit it, “success.jsp” is shown with the entered Book details.
Finally, the source code of two JSP files:-
form.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="portlet" uri="http://java.sun.com/portlet_2_0"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<html>
	<head>
		<title></title>
	</head>
	<body>
	<portlet:renderURL var="go"></portlet:renderURL>
		<form:form method="post" commandName="book" action="${go}">
			<table>
				<tr>
					<td>Name:</td><td><form:input path="name" /></td>
					<td><font color="red"><form:errors path="name" /></font></td>
				</tr>
				<tr>
					<td>Price:</td><td><form:input path="price"/></td>
					<td><font color="red"><form:errors path="price" /></font></td>
				</tr>
				<tr>

					<td>Author:</td><td><form:input path="author"/></td>
					<td><font color="red"><form:errors path="author"  /> </font></td>
				</tr>
				<tr>
					<td>Email:</td><td><form:input path="email"/></td>
					<td><font color="red"><form:errors path="email" /></font></td>
				</tr>
				</table>
				<input name="submitBook" type="submit" value="Create"  />
		</form:form>
	</body>
</html>


success.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="portlet" uri="http://java.sun.com/portlet_2_0"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
	<body>
<table border="1">
	<tbody>
		<tr>
			<td>${submittedBook.name}</td><td> is the Book's name.</td>
		</tr>
		<tr>
			<td>${submittedBook.price}</td><td> is the Book's price.</td>
		</tr>
		<tr>
			<td>${submittedBook.author}</td><td> is the Author's name.</td>
		</tr>
		<tr>
			<td>${submittedBook.email}</td><td> is the Author's email id.</td>
		</tr>
	</tbody>
</table>
	</body>
</html>

And lastly, messages.properties file for custom messages in case of erroneous input by user.

Keep this too in WEB-INF directory.

NotEmpty.book.name=Please enter name
NotEmpty.book.email=Do not be lazy and write the e-mail Id
NotEmpty.book.author=Please write Author's name
Digits.book.price=Enter the price in numbers
Email.book.email=Enter a valid Email ID

That’s all for this one. If you have any doubts I’ll suggest you to read Spring’s Documentation 😉
And if still not satisfied,  fire here, and we’ll see what we can do. 🙂