Showing posts with label Spring. Show all posts
Showing posts with label Spring. Show all posts

Monday, May 21, 2012

Spring MVC 3: Part 2 - Form Processing

Overview:
This will is a TWO part series article that looks at Spring MVC 3. To better understand the usage of the framework + to keep the tutorial short and keep the reader interested, I have split this into TWO parts.

Part 1: Listing and Viewing Person Details (Retrieve)
Part 2: Form Processing ( Create, Update and Delete)

The example used for both the articles will be same, and will be concentrating on CRUD operations. The example will be a People Management Application.

The sample code for BOTH these articles are here.

Part 2: Form Processing (Create, Update and Delete)

Application Demo:


Listing All People Details.

Edit Details of a Person




Project Structure: Following is the project structure used in the article (Maven wed application).

Java package structure

Web app structure

Step 1: Creating the Web Project.

Refer to Part 1.

Step 2: Maven Dependencies (pom.xml)


Refer to Part 1.

Step 3: Defining the Spring MVC Model, and Updated Backend Logic.

Person.java - represent the M in MVC(Refer Part 1).

 package org.fazlan.spring.mvc.model;  
 public class Person {  
   //model properties
   private Long id;  
   . . .

   // model constructors  
   public Person(long id, String firstName, String lastName) {  
   . . .
   }  

   // getter/setter and rest of the methods
   . . .  
 }  

IManager.java and PersonManager - the updated backend service implementation.

IManager.java

 package org.fazlan.spring.mvc.manager;  

 import java.util.List;  

 public interface IManager<T> {  
   List<T> getAll();  
   T get(Long id);  
   void save(T t);  
   void update(T t);  
   void delete(T t);  
 }  

PersonManager.java

  package org.fazlan.spring.mvc.manager; 
  
  import org.fazlan.spring.mvc.model.Person;   
  import java.util.ArrayList;   
  import java.util.HashMap;   
  import java.util.List;   
  import java.util.Map;  
 
  public class PersonManager implements IManager&lt;Person&gt;{   
   private final Map&lt;Long, Person&gt; PERSON_MAP = new HashMap&lt;Long, Person&gt;();   
   private static Long INDEX = 1L;   
   {   
    PERSON_MAP.put(INDEX, new Person(INDEX, "First Name", "Second Name"));   
   }   
   @Override   
   public List&lt;Person&gt; getAll() {   
    return new ArrayList&lt;Person&gt;(PERSON_MAP.values());   
   }   
   @Override   
   public Person get(Long id) {   
    return PERSON_MAP.get(id);   
   }   

   &lt;!-- Newly Added CUD Operation --&gt;
   @Override   
   public void save(Person person) {   
    person.setId(++INDEX);   
    update(person);   
   }   
   @Override   
   public void update(Person person) {   
    PERSON_MAP.put(person.getId(), person);   
   }   
   @Override   
   public void delete(Person person) {   
    PERSON_MAP.remove(person.getId());   
   }   
  }   

Step 4: Updated Spring MVC Controller.
A controller receives web requests, performs business logic, and populates the model (Person.java) for the view to present.

 package org.fazlan.spring.mvc.controllers;
  
 import org.fazlan.spring.mvc.manager.IManager;  
 import org.fazlan.spring.mvc.model.Person;  
 import org.fazlan.spring.mvc.validators.PersonValidator;  
 import org.springframework.beans.factory.annotation.Autowired;  
 import org.springframework.beans.propertyeditors.StringTrimmerEditor;  
 import org.springframework.stereotype.Controller;  
 import org.springframework.ui.Model;  
 import org.springframework.validation.BindingResult;  
 import org.springframework.web.bind.WebDataBinder;  
 import org.springframework.web.bind.annotation.*;  
 import org.springframework.web.bind.support.SessionStatus;  

 import java.util.List;  

 @Controller  
 @SessionAttributes("person")  
 public class PersonForm {  
   @Autowired  
   private IManager<Person> manager;
  
   @Autowired  
   private PersonValidator validator;
  
   @RequestMapping("/list")  
   @ModelAttribute("personList")  
   public List<Person> getAll() {  
     return manager.getAll();  
   }  

   @RequestMapping("/view")  
   public Person get(@RequestParam(value = "id", required = true) Long personId) {  
     return manager.get(id);  
   }  

   @InitBinder  
   public void initBind(WebDataBinder binder) {  
     binder.setDisallowedFields("id");  
     binder.setRequiredFields("firstName", "lastName");  
     binder.registerCustomEditor(String.class, new StringTrimmerEditor(false));  
   }  

   @RequestMapping(value="/add", method = RequestMethod.GET)  
   public Person setup(@RequestParam(value = "id", required = false) Long personId) {  
     Person p;  
     if (personId == null) {  
       p = new Person();  
     } else {  
       p = manager.get(personId);  
     }  
     return p;  
   }  

   @RequestMapping(value="/add", params = "create", method = RequestMethod.POST)  
   public String save(Person person, BindingResult result, SessionStatus status) {  

     validator.validate(person, result);  

     if (result.hasErrors()) {  
       return "add";  
     } else {  
       manager.save(person);  
       status.setComplete();  
       return "redirect:list.html";  
     }  
   }  

   @RequestMapping(value="/add", params = "update", method = RequestMethod.POST)  
   public String update(Person person, BindingResult result, SessionStatus status) {  

     validator.validate(person, result);  

     if (result.hasErrors()) {  
       return "add";  
     } else {  
       manager.update(person);  
       status.setComplete();  
       return "redirect:list.html";  
     }  
   }  

   @RequestMapping(value="/add", params = "delete", method = RequestMethod.POST)  
   public String delete(Person person, BindingResult result, SessionStatus status) {  
     manager.delete(person);  
     status.setComplete();  
     return "redirect:list.html";  
   }  
 }  

The above class defined the controller to handle the requests for managing a Person. For now, let's look at the following elements,

Form Backing Object
This is used to pre-populate the data in the form. Lets look at the following code snippet to better understand form backing object.

@RequestMapping(value="/add", method = RequestMethod.GET)  
public Person setup(@RequestParam(value = "id", required = false) Long personId) {  
  Person p;  
  if (personId == null) {  
    p = new Person();  
  } else {  
    p = manager.get(personId);  
  }  
  return p;  
}  

When the controller receives a HTTP.GET request, the setup() gets invoked and populates the form with a Person JavaBean based on the personId parameter. When the personId is available, then it's a request for either update or delete operation, and hence an existing Person JavaBean object is returned. If the personId parameter is empty, then the request is for create new operation, and hence a new Person JavaBean object is returned.

Saving, Updating and Deleting
These operations are pretty much alike. They receive data (Person JavaBean argument) from the form and process the backend logic.

   @RequestMapping(value="/add", params = "create", method = RequestMethod.POST)  
   public String save(Person person, BindingResult result, SessionStatus status) {  
      . . .
   }  

   @RequestMapping(value="/add", params = "update", method = RequestMethod.POST)  
   public String update(Person person, BindingResult result, SessionStatus status) {  
      . . .
   }  

   @RequestMapping(value="/add", params = "delete", method = RequestMethod.POST)  
   public String delete(Person person, BindingResult result, SessionStatus status) {  
     . . .  
   }  


The params attribute in each of the above method signatures refer to a parameter passed by the HTML form into the controller.

 . . .  
 <form:form method="post" commandName="person" action="add.html" cssClass="box-form-a">  
    . . .  
    <button type="submit" name="create"><spring:message code="navigation.add"/></button>  
    . . .  
    <button type="submit" name="update"><spring:message code="navigation.edit"/></button>  
    <button type="submit" name="delete"  
            onclick="return confirm('Are you sure to delete ${person.firstName} ${person.lastName}?')">  
          <spring:message  
              code="navigation.delete"/></button>  
   . . .  
 </form:form>  
 . . .  

Here, they are names of the buttons in the HTML form., and when one of those buttons clicked, the corresponding method will be invoked.

Returning Logical Views

Please note that some of the methods return a String value. When a String is returned from a method annotated with @RequestMapping, it represents a logical view name. Here, we are telling Spring exactly which page to display next.

As an example,  the create() and update() methods takes the user back to /jsp/add.jsp if any validation errors found. If the input is valid, then /jsp/list.jsp page is displayed.

The redirect: prefix triggers an HTTP redirect to the browser. This is required when delegating the response to another controller, rather than just rendering the view.

In this example, when valid data has been submitted from the form, it takes the user to the people list page. Redirection ensures that the getAll() method is called on the PersonForm class, and the necessary data is added to the model.


@SessionAttributes
The Person object returned by setUp() is not the same object as the one passed into the create(), update() or delete() methods. Thus, only data from the form (which doesn't include all of the properties in our backing object) will be bound to the Person objects in these methods. 


However, more often than not, what we really need is to access the original object (one populated in the setup() method) plus any changes made to data on the form.


The type level @SessionAttributes annotation does just this by specifying the objects, by name or by type, to be kept in session between requests. The setComplete() method on the SessionStatus class, marks session processing as complete, and allows the session attributes to be cleaned up.

Step 5: Defining the Spring MVC Form Validation
This section will cover some of the annotations used in the controller for processing data.

@InitBinder
Is used to bind the data between the HTML form and the controller.
 @InitBinder   
 public void initBind(WebDataBinder binder) {   
  binder.setDisallowedFields("id");   
  binder.setRequiredFields("firstName", "lastName");   
  binder.registerCustomEditor(String.class, new StringTrimmerEditor(false));   
 }  

setDisallowedFields() - registers fields that are not allowed for binding. This example makes sure that the user does not make potentially unauthorized changes(e.i: Inspect Element from the browser)

setRequiredFields()      - lists the form fields that are mandatory. An error will be raised if any values for items in the list are missing.


Custom Validation
The following is how you can introduce your own custom validation logic into the controllers. Then, from the controller, you can invoke these validation methods.

@RequestMapping(value="/add", params = "create", method = RequestMethod.POST)   
public String save(Person person, BindingResult result, SessionStatus status) {   
 validator.validate(person, result);   
  . . .  
}   
@RequestMapping(value="/add", params = "update", method = RequestMethod.POST)   
public String update(Person person, BindingResult result, SessionStatus status) {   
 validator.validate(person, result);   
 . . .  
}      

Validation Error Codes
msg-properties/messages_en_US.properties
msg-properties/messages.properties

 person.details=Person Details  
 person.firstName=First Name  
 person.lastName=Second Name  
 field.required=Required field missing  
 firstName=First Name  
 required=Required field missing  
The 'required' entry is a special code used by Spring when a field that is specified in the setRequiredFields() method, is not supplied.

Rending the Errors on View 
To include the errors on the view, include the tag along side each of the tags in our JSP page.

 <table class="gradient">  
   <tr>  
     <td>First Name</td>  
     <td>  
       <form:input path="firstName"/><form:errors path="firstName" cssClass="errors"/>  
     </td>  
   </tr>  
   <tr>  
     <td>Last Name</td>  
     <td><form:input path="lastName"/><form:errors path="lastName" cssClass="errors"/></td>  
   </tr>  
 </table>  


Step 6: Updated Spring MVC Views.


add.jsp
Now, we introduce a new JSP page to create and update People. The same page is used for both the operations.
Create a Person
When the add.html gets a HTTP.GET request without the id parameter, the form backing object returns a new Person instance, and populates the view.

As an example, the following snippet in the /jsp/list.jsp would called when creating a new Person.
 <a href='add.html'><spring:message code="navigation.add"/></a>  

Update a Person
Similarly, when the add.html gets a HTTP.GET request with the id parameter, the form backing object returns an existing Person instance corresponding to the given id parameter, and populates the view.

As an example, the following snippet in the /jsp/list.jsp would called when creating a new Person.
 <a href="add.html?id=${person.id}"><spring:message code="navigation.edit"/></a>  

The isNew() method on the Person class from the model is used to determine the mode of the screen.
 public boolean isNew() {  
     return id == null;  
 }  


add.jsp JSP

 <body>  
 <div>  
   <form:form method="post" commandName="person" action="add.html" cssClass="box-form-a">  
     <c:choose>  
       <c:when test="${person.new}">  
         <h1>Sign-up Here</h1>  
         <p>Person registration form</p>  
       </c:when>  
       <c:otherwise>  
         <h1>Update Here</h1>  
         <p>Person updation form</p>  
       </c:otherwise>  
     </c:choose>  
     <table class="gradient">  
       <tr>  
         <td>First Name</td>  
         <td>  
           <form:input path="firstName"/><form:errors path="firstName" cssClass="errors"/>  
         </td>  
       </tr>  
       <tr>  
         <td>Last Name</td>  
         <td><form:input path="lastName"/><form:errors path="lastName" cssClass="errors"/></td>  
       </tr>  
     </table>  
     <c:choose>  
       <c:when test="${person.new}">  
         <button type="submit" name="create"><spring:message code="navigation.add"/></button>  
       </c:when>  
       <c:otherwise>  
         <button type="submit" name="update"><spring:message code="navigation.edit"/></button>  
         <button type="submit" name="delete"  
             onclick="return confirm('Are you sure to delete ${person.firstName} ${person.lastName}?')">  
           <spring:message  
               code="navigation.delete"/></button>  
       </c:otherwise>  
     </c:choose>  
   </form:form>  
   <a href="list.html"><spring:message code="navigation.back"/></a>  
 </div>  
 </body>  


Step 7: Spring MVC Configuration


Refer to Part 1.


Step 8: Building and Deploying the Application

Refer to Part 1.


Now, you can access the application with the following URL.
http://localhost:8080/org.fazlan.spring.mvc/list.html

Summary:
The Part 2 of the Spring MVC 3 article focused on how to use the framework to process form data and render on JSPs.

The sample code for BOTH these articles are here.

That's all Folks!!!

Spring MVC 3: Part 1 - Listing and Viewing

Overview:
This will be a TWO part series article that looks at Spring MVC 3. To better understand the usage of the framework + to keep the tutorial short and keep the reader interested, I have split this into TWO parts.

Part 1: Listing and Viewing Person Details (Retrieve)
Part 2: Form Processing ( Create, Update and Delete)

The example used for both the articles will be same, and will be concentrating on CRUD operations. The example will be a People Management Application.

The sample code for BOTH these articles are here.

Part 1: Listing and Viewing Person Details (Retrieve)

Application Demo:


Listing All People Details.

View Details of a Person


Project Structure: Following is the project structure used in the article (Maven wed application).

Java package structure

Web app structure

Step 1: Creating the Web Project.

mvn archetype:generate -DgroupId=org.fazlan -DartifactId=org.fazlan.spring.mvc -Dversion=1.0.0-SNAPSHOT -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false

Step 2:Updating the Maven Dependencies (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/maven-v4_0_0.xsd">  
   <modelVersion>4.0.0</modelVersion>  
   <groupId>org.fazlan</groupId>  
   <artifactId>org.fazlan.spring.mvc</artifactId>  
   <packaging>war</packaging>  
   <version>1.0.0-SNAPSHOT</version>  
   <name>org.fazlan.spring.mvc</name>  
   <url>http://maven.apache.org</url>  
   <dependencies>  
     <dependency>  
       <groupId>junit</groupId>  
       <artifactId>junit</artifactId>  
       <version>3.8.1</version>  
       <scope>test</scope>  
     </dependency>  
     <dependency>  
       <groupId>javax.servlet</groupId>  
       <artifactId>servlet-api</artifactId>  
       <version>2.5</version>  
     </dependency>  
     <dependency>  
       <groupId>javax.servlet.jsp</groupId>  
       <artifactId>jsp-api</artifactId>  
       <version>2.1</version>  
       <scope>provided</scope>  
     </dependency>  
     <dependency>  
       <groupId>taglibs</groupId>  
       <artifactId>standard</artifactId>  
       <version>1.1.2</version>  
     </dependency>  
     <dependency>  
       <groupId>commons-logging</groupId>  
       <artifactId>commons-logging</artifactId>  
       <version>1.1.1</version>  
     </dependency>  
     <dependency>  
       <groupId>javax.servlet</groupId>  
       <artifactId>jstl</artifactId>  
       <version>1.2</version>  
     </dependency>  
     <!-- Spring 3 dependencies -->  
     <dependency>  
       <groupId>org.springframework</groupId>  
       <artifactId>spring-core</artifactId>  
       <version>${org.springframework.version}</version>  
     </dependency>  
     <dependency>  
       <groupId>org.springframework</groupId>  
       <artifactId>spring-web</artifactId>  
       <version>${org.springframework.version}</version>  
     </dependency>  
     <dependency>  
       <groupId>org.springframework</groupId>  
       <artifactId>spring-webmvc</artifactId>  
       <version>${org.springframework.version}</version>  
     </dependency>  
   </dependencies>  
   <build>  
     <finalName>springmvc</finalName>  
     <plugins>  
       <plugin>  
         <groupId>org.mortbay.jetty</groupId>  
         <artifactId>maven-jetty-plugin</artifactId>  
         <version>6.1.10</version>  
       </plugin>  
       <plugin>  
         <groupId>org.apache.maven.plugins</groupId>  
         <artifactId>maven-compiler-plugin</artifactId>  
         <version>2.4</version>  
         <configuration>  
           <source>1.6</source>  
           <target>1.6</target>  
         </configuration>  
       </plugin>  
     </plugins>  
   </build>  
   <properties>  
     <org.springframework.version>3.1.1.RELEASE</org.springframework.version>  
   </properties>  
 </project>  

Step 3: Defining the Spring MVC Model, Backend Logic.

Person.java - represent the M in MVC.

 package org.fazlan.spring.mvc.model;  
 public class Person {  
   private Long id;  
   private String firstName;  
   private String lastName;  
   public Person() {  
   }  
   public Person(long id, String firstName, String lastName) {  
     this.id = id;  
     this.firstName = firstName;  
     this.lastName = lastName;  
   }  
   public boolean isNew() {  
     return id == null;  
   }  
   public Long getId() {  
     return id;  
   }  
   public void setId(Long id) {  
     this.id = id;  
   }  
   public String getFirstName() {  
     return firstName;  
   }  
   public void setFirstName(String firstName) {  
     this.firstName = firstName;  
   }  
   public String getLastName() {  
     return lastName;  
   }  
   public void setLastName(String lastName) {  
     this.lastName = lastName;  
   }  
   @Override  
   public boolean equals(Object o) {  
     if (this == o) return true;  
     if (!(o instanceof Person)) return false;  
     Person person = (Person) o;  
     return id == person.id && !(firstName != null ? !firstName.equals(person.firstName) : person.firstName != null) && !(lastName != null ? !lastName.equals(person.lastName) : person.lastName != null);  
   }  
   @Override  
   public int hashCode() {  
     int result = (int) (id ^ (id >>> 32));  
     result = 31 * result + (firstName != null ? firstName.hashCode() : 0);  
     result = 31 * result + (lastName != null ? lastName.hashCode() : 0);  
     return result;  
   }  
 }  

IManager.java and PersonManager - represents the backend service implementation.

IManager.java

 package org.fazlan.spring.mvc.manager;  

 import java.util.List;  

 public interface IManager<T> {  
   List<T> getAll();  
   T get(Long id); 
 }  

PersonManager.java

  package org.fazlan.spring.mvc.manager; 
  
  import org.fazlan.spring.mvc.model.Person;   
  import java.util.ArrayList;   
  import java.util.HashMap;   
  import java.util.List;   
  import java.util.Map;  
 
  public class PersonManager implements IManager&lt;Person&gt;{   
   private final Map&lt;Long, Person&gt; PERSON_MAP = new HashMap&lt;Long, Person&gt;();   
   private static Long INDEX = 1L;   
   {   
    PERSON_MAP.put(INDEX, new Person(INDEX, "First Name", "Second Name"));   
   }   
   @Override   
   public List&lt;Person&gt; getAll() {   
    return new ArrayList&lt;Person&gt;(PERSON_MAP.values());   
   }   
   @Override   
   public Person get(Long id) {   
    return PERSON_MAP.get(id);   
   }
  }   

Step 4: Defining the Spring MVC Controller.
A controller receives web requests, performs business logic, and populates the model (Person.java) for the view to present.

 package org.fazlan.spring.mvc.controllers;
  
 import org.fazlan.spring.mvc.manager.IManager;  
 import org.fazlan.spring.mvc.model.Person;  
 import org.fazlan.spring.mvc.validators.PersonValidator;  
 import org.springframework.beans.factory.annotation.Autowired;  
 import org.springframework.beans.propertyeditors.StringTrimmerEditor;  
 import org.springframework.stereotype.Controller;  
 import org.springframework.ui.Model;  
 import org.springframework.validation.BindingResult;  
 import org.springframework.web.bind.WebDataBinder;  
 import org.springframework.web.bind.annotation.*;  
 import org.springframework.web.bind.support.SessionStatus;  

 import java.util.List;  

 @Controller  
 @SessionAttributes("person")  
 public class PersonForm {  
   @Autowired  
   private IManager<Person> manager;
  
   @RequestMapping("/list")  
   @ModelAttribute("personList")  
   public List<Person> getAll() {  
     return manager.getAll();  
   }  

   @RequestMapping("/view")  
   public Person get(@RequestParam(value = "id", required = true) Long personId) {  
     return manager.get(id);  
   }    
 }  

The above class defined the controller to handle the requests for managing a Person. For now, let's look at the following elements,

@Controller
Designates a POJO class as a web controller. Spring can automatically detect controller classes using class path scanning, and make them available to receive requests from end users. Equivalent to implementing the Controller interface in Spring MVC 2.

@RequestMapping
This annotation maps web request URLs to Java classes and methods. The above code snippet maps the URL paths /list and /view to the getAll() and get() methods respectively.

@ModelAttribute
This annotation binds the return value of a method to a named attribute in the view(JSP). The getAll() method returns a list of Person JavaBeans, and the @ModelAttribute annotation binds it to an attribute called personList in the view, for subsequent retrieval by the view.

The get() method also returns a Person JavaBean into the view, but this time no @ModelAttribute annotation is specified. In this case, Spring uses the non-qualified class name, 'person', as the attribute name.

For instance, the get() method could have annotated as below for better readability of the code.

 @RequestMapping("/view")   
 @ModelAttribute("person")   
 public Person get(@RequestParam(value = "id", required = true) Long personId) {   
    return manager.get(id);   
 }   

@RequestParam
This annotation binds HTTP request parameters to method arguments in the controller.

In above, the get() method needs to know the identifier (personId) of the Person JavaBean that it is to be returned. The @RequestParam annotation takes the 'id' request parameter from the URL, and maps it to the personId argument of the method. The parameter is mandatory (required=true) so the URL must be ending like /view.html?id=1, or an exception will be generated.

Step 5: Defining the Spring MVC View
After the controller process the request, the view represent the data from the model. We use JSPs and JSTL(Java Standard Tag Library) to display the data in our application.

Logical Views

Firstly, we must define the logical view names to let Spring know, which view has to be rendered. By default, it is derived from the URL path of our request.

For example:
/list.html transformed to view name called list
/view.html transformed to view name called view

If needed, we can override the default by returning a specific view name from our controller, but for now we can just rely on the default.

Physical Views

list.jsp
The page displays a list of people. Each person record is a link to a page which shows further details about that person. We use JSTL custom tags and the JSP expression language to retrieve data from the model and construct the HTML table.

 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>  
 <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> 
 <body>  
 <div>  
   <h1><spring:message code="person.details"/></h1>  
   <table class="gradient">  
     <tr>  
       <th><spring:message code="person.firstName"/></th>  
       <th><spring:message code="person.lastName"/></th>  
       <th><spring:message code="person.action"/></th>  
     </tr>  
     <c:forEach items="${personList}" var="person">  
       <tr>  
         <td>${person.firstName}</td>  
         <td>${person.lastName}</td>  
         <td>  
           <a href="view.html?id=${person.id}"> <spring:message code="navigation.view"/> </a>/<a  
             href="add.html?id=${person.id}"><spring:message code="navigation.edit"/></a>  
         </td>  
       </tr>  
     </c:forEach>  
   </table>  
 </div>  
 <a href='add.html'><spring:message code="navigation.add"/></a>  
 </body>  

The personList collection, which was added to the model by the getAll() method in the PersonForm class, is now accessible by the JSP expression language. The forEach tag iterates over the collection of Person JavaBeans, using the firstName and lastName property for the display value, and the id property in the link to the details page.

view.jsp
The page displays the details of an individual.

 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>  
 <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> 
 <body>  
   <h1><spring:message code="person.details"/></h1>  
   <table class="gradient">  
    <tr>  
     <td><spring:message code="person.firstName"/></td>  
     <td>${person.firstName}</td>  
    </tr>  
    <tr>  
     <td><spring:message code="person.lastName"/></td>  
     <td>${person.lastName}</td>  
    </tr>  
   </table>  
   <a href="list.html"><spring:message code="navigation.back"/></a>  
 </body>  

The data is retrieved from the Person JavaBean, which was added to the model by the get() method in the PersonForm class

View Resolver

After defining logical and physical view names, a view resolver is used to map them and display. Spring provides several view resolvers for technologies such as Velocity templates and XSLT, but we will use Spring's InternalResourceViewResolver class to map the view name to a physical JSP file.

For example:
list is mapped to /jsp/list.jsp
view is mapped to /jsp/view.jsp

Following is how logical view names are mapped to physical files. In this case, the file name will be made up of:

    /jsp/ + physical_view_name + .jsp
For example, a view name list will result in the /jsp/list.jsp file.

This separation of logical view names from view resolvers allows the controllers to produce data models, without being tied to a particular view technology.

Step 6: Spring MVC Configuration
In Spring, front controller pattern called DispatcherServlet dispatches HTTP requests to the appropriate controller. This we define in the web.xml.

web.xml
To work with the latest JSTL and JSP-API, you need to use the latest version of web.xml (as highlighted).

 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
 xmlns="http://java.sun.com/xml/ns/javaee"  
 xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"  
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  
 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">  
  <display-name>Archetype Created Web Application</display-name>  
   <servlet>  
     <servlet-name>springmvc</servlet-name>  
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
     <load-on-startup>1</load-on-startup>  
   </servlet>  
   <servlet-mapping>  
     <servlet-name>springmvc</servlet-name>  
     <url-pattern>*.html</url-pattern>  
   </servlet-mapping>  
   <welcome-file-list>  
     <welcome-file>  
      /list.html  
     </welcome-file>  
    </welcome-file-list>  
 </web-app>  

Spring Configuration File (springmvc.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"  
     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">  

   <context:annotation-config/>  
   <context:component-scan base-package="org.fazlan.spring.mvc"/>  

   <bean id="personValidator" class="org.fazlan.spring.mvc.validators.PersonValidator"/>  
   <bean id="personManager" class="org.fazlan.spring.mvc.manager.PersonManager"/>  
   <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
     <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>  
     <property name="prefix" value="/jsp/"/>  
     <property name="suffix" value=".jsp"/>  
   </bean>  
   <!-- Access resource bundles with the specified basename -->  
   <bean id="messageSource"  
      class="org.springframework.context.support.ReloadableResourceBundleMessageSource">  
     <property name="basename" value="msg-properties/messages"/>  
   </bean>  
 </beans>  

Step 7: Building and Deploying the Application

$ mvn clean install
$ mvn jetty:run

mvn:jetty:run - would run the web app on the jetty server.

Now, you can access the application with the following URL.
http://localhost:8080/org.fazlan.spring.mvc/list.html

Summary:
The Part 1 of the Spring MVC 3 article focused on how to use the framework for retrieving data and rendering on JSPs. The next part will concentrate on how to handle HTML Form processing.

The sample code for BOTH these articles are here.

That's all Folks!!!

Saturday, April 14, 2012

Apache Axis2 Tutorial: Integrating with Spring 3 and Hibernate 3

Overview:
This article looks at how you can integrate Spring and Hibernate with Apache Axis2. Axis2 also enables making use of Spring and Hibernate mush similar to Apache CXF( Tutorial on Apache CXF with Spring and Hibernate). This is a simple but a comprehensive tutorial. We'll be testing the service's REST endpoint using CURL.

The sample code for this project can be found here.

Prerequisite:
JDK >= 1.5.x
Maven >= 2.2.x
MySQL

Project Structure: Following is the project structure I have used (Maven WAR project).
Java class structure:


Resource structure:


Step 1: Creating the Database Table
 CREATE TABLE PERSON (
PERSON_ID BIGINT AUTO_INCREMENT,
FIRST_NAME VARCHAR(30),
LAST_NAME VARCHAR(30),
PRIMARY KEY (PERSON_ID)
)

Step 2: Maven Dependencies (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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.fazlan</groupId>
<artifactId>org.fazlan.employee.axis2.orm.spring.service</artifactId>
<packaging>aar</packaging>
<version>1.0-SNAPSHOT</version>
<name>org.fazlan.employee.axis2.orm.spring.service</name>
<url>http://maven.apache.org</url>
<build>
<plugins>
  <plugin>
    <groupId>org.apache.axis2</groupId>
    <artifactId>axis2-aar-maven-plugin</artifactId>
    <version>1.6.1</version>
    <!--<version>${orbit.version.axis2}</version>-->
    <extensions>true</extensions>
    <configuration>
      <aarName>org.fazlan.employee.axis2.orm.spring.service</aarName>
    </configuration>
  </plugin>
</plugins>
</build>
<dependencies>
<!-- Axis2 -->
<dependency>
  <groupId>org.apache.axis2</groupId>
  <artifactId>axis2</artifactId>
  <version>${org.apache.axis2.version}</version>
</dependency>
<dependency>
      <groupId>org.apache.axis2</groupId>
      <artifactId>axis2-spring</artifactId>
      <version>${org.apache.axis2.version}</version>
    </dependency>
<!-- Spring framework -->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-core</artifactId>
  <version>${org.springframework.version}</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>${org.springframework.version}</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aop</artifactId>
  <version>${org.springframework.version}</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-beans</artifactId>
  <version>${org.springframework.version}</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context-support</artifactId>
  <version>${org.springframework.version}</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-tx</artifactId>
  <version>${org.springframework.version}</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-jdbc</artifactId>
  <version>${org.springframework.version}</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-orm</artifactId>
  <version>${org.springframework.version}</version>
</dependency>
<!-- MySQL database driver -->
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.9</version>
</dependency>
<!-- Hibernate framework -->
<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-core</artifactId>
  <version>${org.hibernate.version}</version>
</dependency>
<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-entitymanager</artifactId>
  <version>${org.hibernate.version}</version>
</dependency>
<!-- Hibernate library dependecy start -->
<dependency>
  <groupId>dom4j</groupId>
  <artifactId>dom4j</artifactId>
  <version>1.6.1</version>
</dependency>
<dependency>
  <groupId>commons-logging</groupId>
  <artifactId>commons-logging</artifactId>
  <version>1.1.1</version>
</dependency>
<dependency>
  <groupId>commons-collections</groupId>
  <artifactId>commons-collections</artifactId>
  <version>3.2.1</version>
</dependency>
<dependency>
  <groupId>antlr</groupId>
  <artifactId>antlr</artifactId>
  <version>2.7.7</version>
</dependency>
<!-- Hibernate library dependency end -->
<!--AspectJ dependency-->
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjrt</artifactId>
  <version>${org.aspectj.version}</version>
</dependency>
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjweaver</artifactId>
  <version>${org.aspectj.version}</version>
</dependency>
 <!-- JUnit testing framework -->
<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.8.1</version>
</dependency>
</dependencies>
<properties>
<org.apache.axis2.version>1.6.1</org.apache.axis2.version>
<org.aspectj.version>1.6.11</org.aspectj.version>
<org.hibernate.version>3.6.0.Final</org.hibernate.version>
<org.springframework.version>3.1.1.RELEASE</org.springframework.version>
</properties>
</project>

Step 3: Defining the POJO, DAO and Service Implementation
- Employee.java

 package org.fazlan.employee.axis2.orm.spring.service.beans;
import java.io.Serializable;
public class Employee implements Serializable {
private Long id;
private String firstName;
private String lastName;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Employee)) return false;
Employee employee = (Employee) o;
return !(firstName != null ? !firstName.equals(employee.firstName) : employee.firstName != null) && !(id != null ? !id.equals(employee.id) : employee.id != null) && !(lastName != null ? !lastName.equals(employee.lastName) : employee.lastName != null);
}
@Override
public int hashCode() {
int result = id != null ? id.hashCode() : 0;
result = 31 * result + (firstName != null ? firstName.hashCode() : 0);
result = 31 * result + (lastName != null ? lastName.hashCode() : 0);
return result;
}
}

- DAO Interface and Implementation

IDao.java
 package org.fazlan.employee.axis2.orm.spring.service.dao;
import java.util.List;
public interface IDao<T> {
Long save(T t);
boolean update(T t);
boolean delete(T t);
T get(Long id);
List<T> getAll();
}

EmployeeDao.java

 package org.fazlan.employee.axis2.orm.spring.service.dao;
import org.fazlan.employee.axis2.orm.spring.service.beans.Employee;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import java.util.List;
public class EmployeeDao extends HibernateDaoSupport implements IDao<Employee>{
public Long save(Employee employee) {
return (Long) getHibernateTemplate().save(employee);
}
public boolean update(Employee employee) {
getHibernateTemplate().update(employee);
return true;
}
public boolean delete(Employee employee) {
getHibernateTemplate().delete(employee);
return true;
}
public Employee get(Long id) {
return getHibernateTemplate().get(Employee.class, id); //To change body of implemented methods use File | Settings | File Templates.
}
public List<Employee> getAll() {
return getHibernateTemplate().find("from Employee");
}
}

- Service Interface and Implementation

IService.java
 package org.fazlan.employee.axis2.orm.spring.service.services;
import java.util.List;
/**
* Created by IntelliJ IDEA.
* User: fazlan
* Date: 3/9/12
* Time: 4:36 PM
* To change this template use File | Settings | File Templates.
*/
public interface IService<T> {
Long add(T t);
boolean update(T t);
boolean delete(T t);
T get(Long id);
List<T> getAll();
}

EmployeeService.java

 package org.fazlan.employee.axis2.orm.spring.service.services;
import org.fazlan.employee.axis2.orm.spring.service.beans.Employee;
import org.fazlan.employee.axis2.orm.spring.service.dao.IDao;
import java.util.List;
public class EmployeeService implements IService<Employee> {
private IDao<Employee> employeeDao;
public Long add(Employee employee) {
return employeeDao.save(employee);
}
public boolean update(Employee employee) {
employeeDao.update(employee);
return true;
}
public boolean delete(Employee employee) {
employeeDao.delete(employee);
return true;
}
public Employee get(Long id) {
return employeeDao.get(id);
}
public List<Employee> getAll() {
return employeeDao.getAll();
}
public void setEmployeeDao(IDao<Employee> employeeDao) {
this.employeeDao = employeeDao;
}
}

Step 4: Defining the Service class to load the Spring Context in Axis2 for this *.aar
EmployeeSpringInit.java

 package org.fazlan.employee.axis2.orm.spring.service.services;
import org.apache.axis2.engine.ServiceLifeCycle;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.description.AxisService;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class EmployeeSpringInit implements ServiceLifeCycle {
private static Log logger = LogFactory
.getLog(EmployeeSpringInit.class);
/**
* this will be called during the deployement time of the service. irrespective
* of the service scope this method will be called
*/
public void startUp(ConfigurationContext ignore, AxisService service) {
ClassLoader classLoader = service.getClassLoader();
ClassPathXmlApplicationContext appCtx = new
  ClassPathXmlApplicationContext(new String[] {"classpath:spring/spring-app-context.xml"}, false);
appCtx.setClassLoader(classLoader);
appCtx.refresh();
if (logger.isDebugEnabled()) {
  logger.debug("\n\nstartUp() set spring classloader via axisService.getClassLoader() ... ");
}
}
/**
* this will be called during the deployement time of the service. irrespective
* of the service scope this method will be called
*/
public void shutDown(ConfigurationContext ignore, AxisService service) {
}
}

Step 5: MySQL Database Connection Properties (hibernate/hbm/db.properties)
 jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/springhibernate
jdbc.username=root
jdbc.password=root123

Step 6: Hibernate Mapping of Employee POJO (hibernate/hbm/Employee.hbm.xml)
 <?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="org.fazlan.employee.axis2.orm.spring.service.beans.Employee" table="PERSON">
<id name="id" column="PERSON_ID" type="long" access="field">
  <generator class="increment" />
</id>
<property name="firstName" type="string">
  <column name="FIRST_NAME" />
</property>
<property name="lastName" type="string">
  <column name="LAST_NAME" />
</property>
</class>
</hibernate-mapping>

Step 7: Defining the Spring Configuration for the Application (spring/spring-app-context.xml)

This is the Spring bean definition file in our application containing all the beans required to run the application.

The following is very important, this class and the spring bean needed to wire it could be used as an alternative to getting the ApplicationContext from the ServletContext.

 <bean id="applicationContext"
class="org.apache.axis2.extensions.spring.receivers.ApplicationContextHolder" />

Putting all together,
 <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation= "http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="applicationContext"
class="org.apache.axis2.extensions.spring.receivers.ApplicationContextHolder" />
<bean class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">
<property name="location" value="classpath:hibernate/properties/db.properties"/>
</bean>
<!-- MySQL datasource -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url" value="${jdbc.url}"/>
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!-- Hibernate session factory -->
<bean id="sessionFactory"
 class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
  <ref bean="dataSource"/>
</property>
<property name="hibernateProperties">
  <props>
    <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
    <prop key="hibernate.show_sql">true</prop>
  </props>
</property>
<property name="mappingLocations">
  <value>classpath:hibernate/hbm/Employee.hbm.xml</value>
</property>
</bean>
<bean id="employeeDao" class="org.fazlan.employee.axis2.orm.spring.service.dao.EmployeeDao">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="employeeSpringService" class="org.fazlan.employee.axis2.orm.spring.service.services.EmployeeService">
<property name="employeeDao" ref="employeeDao"/>
</bean>
</beans>

Step 8: Defining your Axis2 Service Configuration (META-INF/services.xml)

EmployeeSpringInit Service: Loading the Spring context
 <service name="EmployeeSpringInit" class="org.fazlan.employee.axis2.orm.spring.service.services.EmployeeSpringInit">
<description>
  This web service initializes Spring.
</description>
<parameter name="ServiceClass">org.fazlan.employee.axis2.orm.spring.service.services.EmployeeSpringInit
</parameter>
<parameter name="ServiceTCCL">composite</parameter>
<parameter name="load-on-startup">true</parameter>
<!--<operation name="springInit">
 <messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
</operation>-->
</service>
Here, we use this service to load the Spring context at the startup of the application.

EmployeeService - The actual service definition.
 <service name="EmployeeService">
<description>
  Weather Spring POJO Axis2 AAR deployment
</description>
<parameter name="ServiceClass">org.fazlan.employee.axis2.orm.spring.service.services.EmployeeService</parameter>
<parameter name="ServiceObjectSupplier">
  org.apache.axis2.extensions.spring.receivers.SpringAppContextAwareObjectSupplier
</parameter>
<excludeOperations>
  <operation>setEmployeeDao</operation>
</excludeOperations>
<parameter name="SpringBeanName">employeeSpringService</parameter>
<parameter name="SpringContextLocation">spring/spring-app-context.xml</parameter>
<messageReceivers>
  <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
           class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
  <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
           class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
</messageReceivers>
</service>

By default, the Axis2 Engine will look for <your.aar>/applicationContext.xml to load the Spring bean configurations.

You can change this by either defining the following property.
 <parameter name="SpringContextLocation">spring/spring-app-context.xml</parameter>

This tells the Axis2 Engine where to locate the Spring application context file for this service. This is very useful when you have multiple Spring application services in the same Axis3 Engine.
Or,
You can place the Spring configuration file alongside the service.xml as in the following format. Axis2 Engine will implicitly detect this.

META-INF/<service-name>-application-context.xml

Putting all together,
 <serviceGroup>
<service name="EmployeeSpringInit" class="org.fazlan.employee.axis2.orm.spring.service.services.EmployeeSpringInit">
<description>
  This web service initializes Spring.
</description>
<parameter name="ServiceClass">org.fazlan.employee.axis2.orm.spring.service.services.EmployeeSpringInit
</parameter>
<parameter name="ServiceTCCL">composite</parameter>
<parameter name="load-on-startup">true</parameter>
<!--<operation name="springInit">
 <messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
</operation>-->
</service>
<service name="EmployeeService">
<description>
  Weather Spring POJO Axis2 AAR deployment
</description>
<parameter name="ServiceClass">org.fazlan.employee.axis2.orm.spring.service.services.EmployeeService</parameter>
<parameter name="ServiceObjectSupplier">
  org.apache.axis2.extensions.spring.receivers.SpringAppContextAwareObjectSupplier
</parameter>
<excludeOperations>
  <operation>setEmployeeDao</operation>
</excludeOperations>
<parameter name="SpringBeanName">employeeSpringService</parameter>
<parameter name="SpringContextLocation">spring/spring-app-context.xml</parameter>
<messageReceivers>
  <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
           class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
  <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
           class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
</messageReceivers>
</service>
</serviceGroup>

Step 9: Building the Project
mvn clean install

Step 10: Deploying the Service
Now you can deploy this service on to any container. Here we'll deploy this on Tomcat server.

You need to copy the following *.jars to <TOMCAT_HOME>/axis2/WEB-INF/lib/ directory (e;i: /home/fazlan/apache-tomcat-6.0.32/webapps/axis2/WEB-INF/lib/)in your Axis2 WAR already deployed on Tomcat.

Spring 3.1.1.RELEASE jars
spring-aop-3.1.1.RELEASE.jar
spring-asm-3.1.1.RELEASE.jar
spring-beans-3.1.1.RELEASE.jar
spring-context-3.1.1.RELEASE.jar
spring-context-support-3.1.1.RELEASE.jar
spring-core-3.1.1.RELEASE.jar
spring-expression-3.1.1.RELEASE.jar
spring-jdbc-3.1.1.RELEASE.jar
spring-orm-3.1.1.RELEASE.jar
spring-tx-3.1.1.RELEASE.jar
spring-web-3.1.1.RELEASE.jar

Hibernate3 jars
hibernate-commons-annotations-3.2.0.Final.jar
hibernate-core-3.6.0.Final.jar
hibernate-entitymanager-3.6.0.Final.jar
hibernate-jpa-2.0-api-1.0.0.Final.jar

Hibernate3 dependent jars
dom4j-1.6.1.jar
slf4j-api-1.6.1.jar
commons-collections-3.2.1.jar
javassist-3.12.0.GA.jar

This is due to the fact Axis2 Engine tries to load the classes from the jars from /axis2/WEB-INF/lib/ rather than locally in the *.aar file. Although, I tried with the following property in the services.xml, it didn't start the service.
 <parameter name="EnableChildFirstClassLoading">true</parameter>

Once, all the above *.jars are copied to /axis2/WEB-INF/lib/ on Tomcat. We are good to deploy the service and test.

Step 11: Testing the Service

Option 1: Testing the SOAP EPR with SOAP UI.

You can use SOAP UI and test the service with http://localhost:8080/axis2/services/EmployeeService?wsdl SOAP endpoint

Option 2: Testing REFTful endpoint using CURL

Install CURL
sudo apt-get install curl

Now, after successfully installing CURL, we are ready to test the services.
Issue the following commands on the terminal.

POST a Resource: Adding a new employee resource.
- Adding the new employee record in the add.xml file.
 <ns:add xmlns:ns="http://services.service.spring.orm.axis2.employee.fazlan.org">
  <ns:employee xmlns:ax21="http://beans.service.spring.orm.axis2.employee.fazlan.org/xsd"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ax21:Employee">
       <ax21:firstName>My FirstName</ax21:firstName>
       <ax21:id>1</ax21:id>
       <ax21:lastName>My LastName</ax21:lastName>
  </ns:employee>
</ns:add>

 curl -v -H "Accept: application/xml" -H "Content-type: application/xml" -X POST -d @add.xml http://localhost:8080/axis2/services/EmployeeService/add

GET Resources:
- Retrieving all the employee resources.
 curl -v -H "Accept: application/xml" http://localhost:8080/axis2/services/EmployeeService/getAll

- Retrieving a employee resource for a given id(id = 1).
 curl -v -H "Accept: application/xml" http://localhost:8080/axis2/services/EmployeeService/get?id=1


PUT a Resource: Updating an existing employee resource.
- Updating an existing employee record in the update.xml file.
 <ns:update xmlns:ns="http://services.service.spring.orm.axis2.employee.fazlan.org">
  <ns:employee xmlns:ax21="http://beans.service.spring.orm.axis2.employee.fazlan.org/xsd"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ax21:Employee">
       <ax21:firstName>Update FirstName</ax21:firstName>
       <ax21:id>1</ax21:id>
       <ax21:lastName>Update LastName</ax21:lastName>
  </ns:employee>
</ns:update>

 curl -v -H "Accept: application/xml" -H "Content-type: application/xml" -X PUT -d @update.xml http://localhost:8080/axis2/services/EmployeeService/update

DELETE a Resource: Deleting an employee for a given id (id=1)
- Deleting an existing employee record in the delete.xml file.
 <ns:delete xmlns:ns="http://services.service.spring.orm.axis2.employee.fazlan.org">
  <ns:employee xmlns:ax21="http://beans.service.spring.orm.axis2.employee.fazlan.org/xsd"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ax21:Employee">
       <ax21:firstName>Update FirstName</ax21:firstName>
       <ax21:id>1</ax21:id>
       <ax21:lastName>Update LastName</ax21:lastName>
  </ns:employee>
</ns:delete>

 curl -i -H "Accept: application/xml" -H "Content-type: application/xml" -X PUT -d @delete.xml http://localhost:8080/axis2/services/EmployeeService/delete

Summary:
This tutorial looked at how we can integrate Spring and Hibernate with Apache Axis2.

The sample code for this project can be found here.