Spring 3 MVC : Handling Forms

Monday, August 15, 2011 Posted by KodeGang 2 comments
Introduction to Spring 3 MVC Framework

Spring MVC is the web component of Spring’s framework. It provides a rich functionality for building robust Web Applications. The Spring MVC Framework is architected and designed in such a way that every piece of logic and functionality is highly configurable. Also Spring can integrate effortlessly with other popular Web Frameworks like Struts, WebWork, Java Server Faces and Tapestry. It means that you can even instruct Spring to use any one of the Web Frameworks. More than that Spring is not tightly coupled with Servlets or JSP to render the View to the Clients. Integration with other View technologies like Velocity, Freemarker, Excel or Pdf is also possible now.

In Spring Web MVC you can use any object as a command or form-backing object; you do not need to implement a framework-specific interface or base class. Spring’s data binding is highly flexible: for example, it treats type mismatches as validation errors that can be evaluated by the application, not as system errors. Thus you need not duplicate your business objects’ properties as simple, untyped strings in your form objects simply to handle invalid submissions, or to convert the Strings properly. Instead, it is often preferable to bind directly to your business objects.

Request Processing Lifecycle



Image courtesy: Springsource

Spring’s web MVC framework is, like many other web MVC frameworks, request-driven, designed around a central servlet that dispatches requests to controllers and offers other functionality that facilitates the development of web applications. Spring’s DispatcherServlet is completely integrated with Spring IoC container and allows us to use every other feature of Spring.

Following is the Request process lifecycle of Spring 3.0 MVC:

  1. The client sends a request to web container in the form of http request.
  2. This incoming request is intercepted by Front controller (DispatcherServlet) and it will then tries to find out appropriate Handler Mappings.
  3. With the help of Handler Mappings, the DispatcherServlet will dispatch the request to appropriate Controller.
  4. The Controller tries to process the request and returns the Model and View object in form of ModelAndView instance to the Front Controller.
  5. The Front Controller then tries to resolve the View (which can be JSP, Freemarker, Velocity etc) by consulting the View Resolver object.
  6. The selected view is then rendered back to client


Features of Spring 3.0

  • Spring 3.0 framework supports Java 5. It provides annotation based configuration support. Java 5 features such as generics, annotations, varargs etc can be used in Spring.
  • A new expression language Spring Expression Language SpEL is being introduced. The Spring Expression Language can be used while defining the XML and Annotation based bean definition.
  • Spring 3.0 framework supports REST web services.
  • Data formatting can never be so easy. Spring 3.0 supports annotation based formatting. We can now use the @DateFimeFormat(iso=ISO.DATE) and @NumberFormat(style=Style.CURRENCY) annotations to convert the date and currency formats.
  • Spring 3.0 has started support to JPA 2.0


Configuring Spring 3.0 MVC

The entry point of Spring 3.0 MVC is the DispatcherServlet. DispatcherServlet is a normal servlet class which implements HttpServlet base class. Thus we need to configure it in web.xml.



spring.mvc

contextConfigLocation


org.springframework.web.context.ContextLoaderListener


dispatcher
org.springframework.web.servlet.DispatcherServlet
1


dispatcher
/
		


index.jsp		




In above code snippet, we have configure DispatcherServlet in web.xml. Note that we have mapped / url pattern with example DispatcherServlet. Thus any url with / pattern will call Spring MVC Front controller.




Image courtesy: Springsource

Once the DispatcherServlet is initialized, it will looks for a file names [servlet-name]-servlet.xml in WEB-INF folder of web application. In above example, the framework will look for file called example-servlet.xml.

Note the above architecture diagram. The WebApplicationContext specified in above diagram is an extension of the plain ApplicationContext with some extra feature necessary for web applications. The WebApplicationContext is capable of resolving themes and it is also associated with corresponding servlet. The WebApplicationContext is bound in the ServletContext, and by using static methods on the RequestContextUtils class you can always look up the WebApplicationContext.

Now create the directory structure as shown in the fallowing Image



After creating the directory Structure just go through the fallowing code, and place the Java classes in appropriate packages.

Employee.java

package com.javacircuit.domain;
/**
* @author Sudarsan Domain Interface Employee
*/
public interface Employee {	
public String getFirstName();
public void setFirstName(String firstName);
public String getLastName();
public void setLastName(String lastName);
public void setEmail(String email);
public String getEmail();	
public String getDesignation();
public void setDesignation(String designation);
}


Then write Implementation for the Domain Employee as shown below.

EmployeeImpl.java
package com.javacircuit.domain.impl;
import java.io.Serializable;
import com.javacircuit.domain.Employee;
/**
* @author Sudarsan Implementing the domain interface Employee
*/
public class EmployeeImpl implements Employee, Serializable {
private static final long serialVersionUID = 1L;
private String firstName;
private String lastName;
private String email;
private String designation;	
@Override
public String getFirstName() {
return firstName;
}
@Override
public void setFirstName(String firstName) {
this.firstName = firstName;
}
@Override
public String getLastName() {
return lastName;
}
@Override
public void setLastName(String lastName) {
this.lastName = lastName;
}
@Override
public String getEmail() {
return email;
}
@Override
public void setEmail(String email) {
this.email = email;
}
@Override
public String getDesignation() {
return designation;
}
// A method to set Employee Priority based on his designation
@Override
public void setDesignation(String designation) {		
this.designation = designation;
}	
@Override
public String toString() {
return "EmployeeImpl [firstName=" + firstName + ", lastName="
+ lastName + ", email=" + email + ", designation="
+ designation + "]";
}
}


In order to provide Services for the domain, create the Interface and its implementation as given below.

EmployeeService.java

package com.javacircuit.service;
import java.util.List;
import com.javacircuit.domain.Employee;
/**
* @author Sudarsan Interface for Employee Services
*/
public interface EmployeeService {
// We can add more methods in future, like removeEmployee, UpdateEmployee	
List<Employee> getAll();
void addEmployee(Employee employee);		
}


EmployeeServiceImpl.java

package com.javacircuit.service.impl;
import java.util.ArrayList;
import java.util.List;
import com.javacircuit.domain.Employee;
import com.javacircuit.service.EmployeeService;
/**
* @author Sudarsan Implementing EmployeeService interface
*/
public class EmployeeServiceImpl implements EmployeeService {
private static List<Employee> employees = new ArrayList<Employee>();
@Override
public List<Employee> getAll() {
return this.employees;
}
@Override
public void addEmployee(Employee employee) {
this.employees.add(employee);
}
}


After Implementing the services write a model class wich represents the Employee as shown below.

EmployeeForm.java

package com.javacircuit.web.model;
public class EmployeeForm {	
private String firstName;
private String lastName;
private String email;
private String designation;	

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;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getDesignation() {		
return designation;
}
public void setDesignation(String designation) {
this.designation = designation;
}
@Override
public String toString() {
return "EmployeeForm [firstName=" + firstName + ", lastName="
+ lastName + ", email=" + email + ", designation="
+ designation + "]";
}	
}


Now, create a Controller to handle Employee operations call this as EmployeeController.

EmployeeController.java

package com.javacircuit.web.controller;
import java.util.List;
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 com.javacircuit.domain.Employee;
import com.javacircuit.domain.impl.EmployeeImpl;
import com.javacircuit.service.EmployeeService;
import com.javacircuit.service.impl.EmployeeServiceImpl;
import com.javacircuit.web.model.EmployeeForm;
@Controller
@RequestMapping("/employeeEntry")
public class EmployeeController {	
@RequestMapping(method = RequestMethod.GET)
public String showEmployeeForm(Model model){
// Display Empty Data Entry Form to User
model.addAttribute(new EmployeeForm());
return "employeeEntry";
}	
@RequestMapping(value ="/create" ,method = RequestMethod.POST)
public String createEmployees(@ModelAttribute("employeeForm") EmployeeForm employeeForm, Model model){
// Get Employee Service
EmployeeService employeeService = new EmployeeServiceImpl();

// Get Field Values from the Form
String firstName = employeeForm.getFirstName();
String lastName = employeeForm.getLastName();
String email = employeeForm.getEmail();
String designation = employeeForm.getDesignation();	

// Create Employee Object
Employee employee = new EmployeeImpl();
employee.setFirstName(firstName);
employee.setLastName(lastName);
employee.setEmail(email);
employee.setDesignation(designation);
// Add Employee to EmployeeService
employeeService.addEmployee(employee); 

// Get List Employee List from Service
List<Employee> employeeList = employeeService.getAll();
// Bind the List in Model		
model.addAttribute("employeeList", employeeList); 
return "/view"; // Return a View, which goes to view.jsp
}
}


After writing all the java source files, configure the DispatcherServlet, and configure View Resolver for JSPs.

dispatcher-servlet.xml





	

	


/WEB-INF/views/


.jsp





In index.jsp, write the fallowing code to forward the page to another JSP page.

index.jsp

<% response.sendRedirect(request.getContextPath()+"/employeeEntry");%>


And now create a JSP with the name employeeEntry and design a form to input employee data as shown below.

employeeEntry.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt_rt"%>
<%@ taglib prefix="s" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form"%>


Employee Data Entry

type="text/css" />


Employee Data Entry


First Name
Last Name
Email
Designation


Now create another JSP called view
as shown below.

view.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt_rt"%>
<%@ taglib prefix="s" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form"%>


Employee List
"
type="text/css" />


Employee Details


First Name Last Name Email Designation

| Add More |



When you build this application you can see the fallowing output





I hosted this application on Ziddu, download it from here http://www.ziddu.com/download/16055764/springapp.rar.html, please write in the comments section if you have any problems running the application.

That's it folks, in the future we can discuss, Spring Validation, Localization and Spring Security etc, so keep visiting the blog.
Labels: