Sunday, December 20, 2015

Spring MVC Exception Handling

In my previous post "spring-form-validation-using-spring" I have describe how to use Spring Validation API to validate forms in Spring. In this post I will describe how to use Spring exception handling mechanism and show exception error messages to the end user. For this example I will use same project that I had used in previous post. 

Prerequisites 
  1. You should have install java in your PC and set path variable correctly (JAVA_HOME, JRE_HOME)
  2. You should have install Eclipse Java EE LUNA 4.4 IDE or any IDE you preferred (In this post I'm Using Eclipse )
  3. You should have the project which completed on my previous post "spring-form-validation-using-spring"

In any application it's required to handle the possible exceptions properly and give appropriate error messages to the end users. In generally exceptions and not shown to the end users because it might confused the end user about the system and next major fact would be it exposes system details to the third party. So it increases the security vulnerability as well.
   
Step 1 Lets handle exceptions in URL mapping controller on our project
First of all lets throw exception programetically. To throw a exception lets update our newUser method inside the UserController as bellow.

@RequestMapping("/addUser")
public String newUser(Model model)
{
model.addAttribute("user", new User());
List<String> prefContctMethods=new ArrayList<String>();
prefContctMethods.add("E-mail");
prefContctMethods.add("Call");
model.addAttribute("prefContct", prefContctMethods);
List<String> sexType=new ArrayList<String>();
sexType.add("Male");
sexType.add("Female");
model.addAttribute("sexType", sexType);
if(true)
throw new UnauthorizedAccessException();
return "newUser";
}

Then if you try to access New User link(http://localhost:8080/SpringFirstWeb/addUser) you will see similar result to below image.


To handle this kind of exceptions Spring provide @ExceptionHandler annotation which use to return the JSP file which should redirect when exception occurs. This annotation can be used to specify which Exceptions should be handled on particular method. To specify that we have to mention exception class names inside two parenthesis.

For a example
  @ExceptionHandler({RuntimeException.class,IOException.class})
public String exceptionHandler()
{
return "exceptionError";
}

with above method our updated UserController class will be similar to below.

package spring.first.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.sun.servicetag.UnauthorizedAccessException;

import spring.first.data.UserService;
import spring.first.data.validator.UserValidator;
import spring.first.model.User;

@Controller
public class UserController {
@Autowired
UserService userService;

@RequestMapping("/userHandling")
public String home()
{
return "userMain";
}
@RequestMapping("/addUser")
public String newUser(Model model)
{
model.addAttribute("user", new User());
List<String> prefContctMethods=new ArrayList<String>();
prefContctMethods.add("E-mail");
prefContctMethods.add("Call");
model.addAttribute("prefContct", prefContctMethods);
List<String> sexType=new ArrayList<String>();
sexType.add("Male");
sexType.add("Female");
model.addAttribute("sexType", sexType);
if(true)
throw new UnauthorizedAccessException();
return "newUser";
}
@ExceptionHandler({RuntimeException.class,IOException.class})
public String exceptionHandler()
{
return "exceptionError";
}
@RequestMapping(value="saveUser", method=RequestMethod.POST )
public String saveUser(@Valid @ModelAttribute User user,Errors errors, Model model)
{
System.out.println(user);
if(errors.hasErrors())
{
List<String> prefContctMethods=new ArrayList<String>();
prefContctMethods.add("E-mail");
prefContctMethods.add("Call");
model.addAttribute("prefContct", prefContctMethods);
List<String> sexType=new ArrayList<String>();
sexType.add("Male");
sexType.add("Female");
model.addAttribute("sexType", sexType);
return "newUser";
}
userService.saveUser(user);
model.addAttribute("users", userService.getMockedUsers());
return "allUsers";
}
@RequestMapping("/allUsers")
public String allUsers( Model model)
{
model.addAttribute("users", userService.getMockedUsers());
return "allUsers";
}
@InitBinder
public void initBinder(WebDataBinder binder)
{
binder.addValidators(new UserValidator());
}
}


Here we have to add new exceptionError.jsp file in to the JSP folder. I will add following content in to this JSP.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
Error Occurred please contact system administrator for further assistance.
</body>
</html>

Lets restart the server and again we try to access New User URL. (http://localhost:8080/SpringFirstWeb/addUser) You can be expect similar interface to below.



We have completed project with Spring MVC Exception handling and  I will add some advanced features of Spring framework in upcoming posts.

Saturday, December 19, 2015

Spring Form validation using Spring Validation API

In my previous post "Spring simple form handling" I have describe how to handle simple data mapping in Spring. In this post I will describe how to use Spring validation API to validate model objects and show appropriate errors on views. For this example I will use same project that I had used in previous post. 

Prerequisites 
  1. You should have install java in your PC and set path variable correctly (JAVA_HOME, JRE_HOME)
  2. You should have install Eclipse Java EE LUNA 4.4 IDE or any IDE you preferred (In this post I'm Using Eclipse )
  3. You should have the project which completed on my previous post "Spring simple form handling"

Step 1 Add Spring Validation API dependency 

As the first step lets add the Spring validation API in to project. To do that double click on pom.xml then click on dependencies. Then click on add. Then type "validation-API" and select javax.validation validation-API as below image.



Step 2 Add Spring Validator class

Right click on src folder and add new class call "UserValidator" as below image. Provide seperate package for validator class. Then click on Add button to specify interface which should validaor class implement.  



Type validator on input field and select spring frame work validator as below image. Then click OK.



You will see two methods which we should implement in our validator class as support and validate method. In support method has a parameter which passes the model class and we have to specify whether we are going to validate that or not by returning true or false. So the method implementation should be similar to this one.

public boolean supports(Class<?> className) {

if(className.equals(User.class))
{
return true;
}
return false;
}

Next is validate method which contains how to validate the specified model objects. It requires two parameters first one will be Model object and second one is errors. In validate method first we have to check whether the object is instance of the required model object. In our example it is User object. In below example it check whether user ID has minimum length of 3 characters and user first name has entered. 
Then if the validation fails then error message should be added to errors object with key value. This key value will use to get error message.

public void validate(Object obj, Errors errors) {
if(obj instanceof User)
{
User user=(User)obj;
if(user.getId().length()<3)
{
errors.rejectValue("id", "user.id", "Id should be minimum 3 charactors");
}

if(user.getFirstName().length()<1)
{
errors.rejectValue("firstName", "user.firstName", "First Name can not be blank");
}
}
       }


Step 3 Update controller method

First to use Spring validator we have to initialize validator class when system loaded. To do that we have to develop method similar to below. That should be annotated using  @InitBinder. 

@InitBinder
public void initBinder(WebDataBinder binder)
{
binder.addValidators(new UserValidator());
}

Then in our controller save method we getting data from client side in that method we need to tell that this user model object should be validated. To give that we have to use @Valid annotation in-front of the User model parameter as show in below bolted word. If there are errors then we have to stay on the user view so we have to check whether there are any errors and view newUser JSP. So saveUser controller method should be modified as bellow.

@RequestMapping(value="saveUser", method=RequestMethod.POST )
public String saveUser(@Valid @ModelAttribute User user,Errors errors, Model model)
{
System.out.println(user);

if(errors.hasErrors())
{
List<String> prefContctMethods=new ArrayList<String>();
prefContctMethods.add("E-mail");
prefContctMethods.add("Call");
model.addAttribute("prefContct", prefContctMethods);
List<String> sexType=new ArrayList<String>();
sexType.add("Male");
sexType.add("Female");
model.addAttribute("sexType", sexType);
return "newUser";
}

userService.saveUser(user);
model.addAttribute("users", userService.getMockedUsers());
return "allUsers";
}


Step 4 Error message show in JSP

Now we have generated validator correctly then we have to show the error messages on JSP file. To show errors on JSP files we use springform:errors tag. In that tag we have to use key that we used to add error in to errors object on validate method in UserValidator class.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="springform" uri="http://www.springframework.org/tags/form" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>New User</title>
</head>
<body>

Enter your User details
<spring:url value="/saveUser" var="springUrl"/>
<springform:form action="${springUrl}" method="POST" modelAttribute="user">
<table style="width:100%">
 <tr>
   <td>User ID</td>
   <td>
    <springform:input path="id"/>
<springform:errors path="id"  />
   </td>
 </tr>
 <tr>
   <td>First Name</td>
   <td>
<springform:input path="firstName"/>
<springform:errors path="firstName"  />
</td>
 </tr>
 <tr>
   <td>Last Name</td>
   <td>
<springform:input path="lastName"/>
<springform:errors path="lastName"  />
</td>
 </tr>
 <tr><td><br/>Address Details</td></tr>
 <tr>
   <td>No</td>
   <td>
<springform:input path="address.no"/>
</td>
 </tr>
 <tr>
   <td>Street</td>
   <td>
<springform:input path="address.Streat"/>
</td>
 </tr>
 <tr>
   <td>City</td>
   <td>
<springform:input path="address.city"/>
</td>
 </tr>  
 <tr>
   <td>Area</td>
   <td>
<springform:input path="address.area"/>
</td>
 </tr>  
 <tr>
   <td>Country</td>
   <td>
<springform:input path="address.country"/>
</td>
 </tr>      
 <tr>
   <td><br/>Preffered Contact Methods</td>
   <td>
<springform:select path="preferredContactMethod" items="${prefContct}"></springform:select>
</td>
 </tr>      
 <tr>
   <td>Gender</td>
   <td>
<springform:radiobuttons id="radio" items="${sexType}" path="sex"/>
</td>
 </tr>      

</table>

<button type="submit"> Submit</button>
</springform:form>

</body>
</html>


Go to Add User link (http://localhost:8080/SpringFirstWeb/addUser). Then do not enter Id and  enter any 3 words in first name and click submit. If You follow the tutorial correctly then you should see following error messages.






You can access this project on GIT hub repository location using following URL https://github.com/NirmalBalasooriya/SpringFormValidation We have completed project with Spring Validation API and in my future post I will add some advanced features of Spring framework in upcoming posts.

Friday, December 18, 2015

Spring Simple Form Handling

On my previous post "Helloworld Spring 4 MVC in Eclipse Luna" I have described setup Spring MVC project in Eclipse step by step. In this post I will describe basic Spring form handling process. I will use the same project to demonstrate this post as well and you can download the previous project source from on following GitHub location https://github.com/NirmalBalasooriya/SpringWeb. 
In this post I will show how to handle simple user details form using Spring Forms and JSTL.

Step 1 Create required model classes
First of lets create some model classes that we are going to use in this demonstration. First of all lets create new model class "User". Right click on "src" folder then go to New->Class. I will provide package as spring.first.model (You can use preferred package name you like) and class name as "User".

Figure 1: Add New User model class

Then lets add another model class "Address" to the same package.


Then I'll add some details in to User model class such as first name, last name, Address reference etc. For the Address class also I'll add details like No, Street Name, City, Province, Country. Then I'll encapsulate two model classes. (Provide limited accessibility to all the variables and provide setters and getter  methods) Please see the content of our two model classes. In addition to that I have override the  toString method so when we print particular object content on this method will be printed.
Address class content
package spring.first.model;

public class Address {
    private int no;
    private String Streat;
    private String city;
    private String area;
    private String country;
    public int getNo() {
        return no;
    }
    public void setNo(int no) {
        this.no = no;
    }
    public String getStreat() {
        return Streat;
    }
    public void setStreat(String streat) {
        Streat = streat;
    }
    public String getCity() {
        return city;
    }
    public void setCity(String city) {
        this.city = city;
    }
    public String getArea() {
        return area;
    }
    public void setArea(String area) {
        this.area = area;
    }
    public String getCountry() {
        return country;
    }
    public void setCountry(String country) {
        this.country = country;
    }
   
    @Override
    public String toString() {
        return "Address [no=" + no + ", Streat=" + Streat + ", city=" + city
                + ", area=" + area + ", country=" + country + "]";
    }

}
User class content

package spring.first.model;

import java.util.Arrays;
import java.util.List;

public class User {
    private String id;
    private String firstName;
    private String lastName;
    private Address address;
    private String[] preferredContactMethod;
    private String sex;
    private List<String> contactNumbers;
  
    public String getId() {
        return id;
    }
    public void setId(String 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;
    }
    public Address getAddress() {
        return address;
    }
    public void setAddress(Address address) {
        this.address = address;
    }
    public String[] getPreferredContactMethod() {
        return preferredContactMethod;
    }
    public void setPreferredContactMethod(String[] preferredContactMethod) {
        this.preferredContactMethod = preferredContactMethod;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public List<String> getContactNumbers() {
        return contactNumbers;
    }
    public void setContactNumbers(List<String> contactNumbers) {
        this.contactNumbers = contactNumbers;
    }
  
    @Override
    public String toString() {
        return "User [id=" + id + ", firstName=" + firstName + ", lastName="
                + lastName + ", address=" + address
                + ", preferredContactMethod="
                + Arrays.toString(preferredContactMethod) + ", sex=" + sex
                + ", contactNumbers=" + contactNumbers + "]";
    }
}

Now we have created our two model classes then lets go ahead with these two. Next lets create mock User service to load static User list and functionality to add newly added users to existing collection.

Step 2 Create mocked User service
Lets add new class "UserService" in new package "spring.first.data" by right click on "SRC" folder then new -> class. Please note that I will not use any database connection for this example. I will use mocked static data content to demonstrate this example.

Figure 2: Add new UserService

I will use following content on my static service.

package spring.first.data;

import java.util.ArrayList;
import java.util.List;

import spring.first.model.Address;
import spring.first.model.User;

public class UserService {
    private static List<User> users;
    public UserService()
    {
        users=new ArrayList<User>();
        loadMockedUsers();
    }
   
    public List<User> getMockedUsers()
    {
        return users;
    }
   
    private void loadMockedUsers()
    {
        User user1=new User();
        user1.setId("U0001");
        user1.setFirstName("Laksh");
        user1.setLastName("Jonsan");
        user1.setPreferredContactMethod(new String[]{"phone","email"});
        user1.setSex("male");
        Address address=new Address();
        address.setNo(1011);
        address.setCity("Collombo");
        address.setCountry("Sri lanka");
        user1.setAddress(address);
        users.add(user1);
       
        User user2=new User();
        user2.setId("U0002");
        user2.setFirstName("Ashly");
        user2.setLastName("Jenuri");
        user2.setPreferredContactMethod(new String[]{"phone"});
        user2.setSex("female");
        Address address2=new Address();
        address2.setNo(225);
        address2.setCity("Gampaha");
        address2.setCountry("Sri lanka");
        user2.setAddress(address2);
        users.add(user2);
    }
   
    public User saveUser(User user)
    {
        users.add(user);
        return findUser(user.getId());
    }
   
    public User findUser(String id)
    {
        for (User user : users) {
            if(user.getId().equalsIgnoreCase(id))
            {
                return user;
            }
        }
        return null;
    }
}


Step 3 Create User controller class

Now lets create UserController class which handles the requests related to the user activities in this project. Right click on spring.first.controller package then go to add -> class. The set class name as UserController.



Then lets add following method in to controller. This will load usermain.jsp in jsp folder. Next step lets add this.

   @RequestMapping("/userHandling")
    public String home()
    {
        return "usermain";
    }


Then lets add related JSP file in to JSP folder inside the WEB-INF JSP foler.
Lets add following content in to this. 

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="springform" uri="http://www.springframework.org/tags/form" %>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>User Handling Page</title>
</head>
<body>
<a href="<spring:url value='/addUser'/>">New User</a>
<br>
<a href="<spring:url value='/allUsers'/>">All Users</a>
</body>
</html>


So now if you run the application you can see the content on

localhost:port//springfirst/userHandling

For my PC it looks as follows

http://localhost:8080/SpringFirstWeb/userHandling

On this JSP we have added two links to add user and view all users. Still we have not added these methods to controller lets add those methods as follows.

@RequestMapping("/addUser")
public String newUser(Model model)
{
model.addAttribute("user", new User());
List<String> prefContctMethods=new ArrayList<String>();
prefContctMethods.add("E-mail");
prefContctMethods.add("Call");
model.addAttribute("prefContct", prefContctMethods);
List<String> sexType=new ArrayList<String>();
sexType.add("Male");
sexType.add("Female");
model.addAttribute("sexType", sexType);
return "newUser";
}

In this I have added two variables in to model which we will use to load data on the JSP. Those two variables are prefContct and sexType. Then after that it will load newUser.jsp. To add this JSP in to JSP folder inside the WEB-INF. Add following content in to that.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="springform" uri="http://www.springframework.org/tags/form" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>New User</title>
</head>
<body>

Enter your User details
<spring:url value="/saveUser" var="springUrl"/>
<springform:form action="${springUrl}" method="POST" modelAttribute="user">
<table style="width:100%">
 <tr>
   <td>User ID</td>
   <td>
    <springform:input path="id"/>
<springform:errors path="id"  />
   </td> 
 </tr>
 <tr>
   <td>First Name</td>
   <td>
<springform:input path="firstName"/>
<springform:errors path="firstName"  />
</td> 
 </tr>
 <tr>
   <td>Last Name</td>
   <td>
<springform:input path="lastName"/>
<springform:errors path="lastName"  />
</td> 
 </tr>
 <tr><td><br/>Address Details</td></tr>
 <tr>
   <td>No</td>
   <td>
<springform:input path="address.no"/>
</td> 
 </tr>
 <tr>
   <td>Street</td>
   <td>
<springform:input path="address.Streat"/>
</td> 
 </tr>
 <tr>
   <td>City</td>
   <td>
<springform:input path="address.city"/>
</td> 
 </tr>    
 <tr>
   <td>Area</td>
   <td>
<springform:input path="address.area"/>
</td> 
 </tr>    
 <tr>
   <td>Country</td>
   <td>
<springform:input path="address.country"/>
</td> 
 </tr>        
 <tr>
   <td><br/>Preffered Contact Methods</td>
   <td>
<springform:select path="preferredContactMethod" items="${prefContct}"></springform:select>
</td> 
 </tr>        
 <tr>
   <td>Gender</td>
   <td>
<springform:radiobuttons id="radio" items="${sexType}" path="sex"/>
</td> 
 </tr>        

</table>

<button type="submit"> Submit</button>
</springform:form>

</body>
</html>

You can see I have used I have used both variables which I have added in to model in the controller.
Following code will generate drop down with values which contains on prefContct.
<springform:select path="preferredContactMethod" items="${prefContct}">

Following line will generate radio button group with values on sexType

<springform:radiobuttons id="radio" items="${sexType}" path="sex"/>

You can see as normal HTML form we can see action method on Spring Forms as well. It will tell which URL mapped should be called on form submission.

Still we have not added this new method in to controller lets add that in to UserController as follows. So whole UserController will be similar to this.

@RequestMapping(value="saveUser", method=RequestMethod.POST )
public String saveUser(@ModelAttribute User user,Errors errors, Model model)
{
System.out.println(user);
return "allUsers";
}

I have added println line to print user objects toString method return value. So we can see whether the actual values are sent to the server or not. After that it will load allUser.JSP file.

package spring.first.controller;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import spring.first.data.UserService;
import spring.first.model.User;

@Controller
public class UserController {

@Autowired
UserService userService;

@RequestMapping("/userHandling")
public String home()
{
return "userMain";
}

@RequestMapping("/addUser")
public String newUser(Model model)
{
model.addAttribute("user", new User());
List<String> prefContctMethods=new ArrayList<String>();
prefContctMethods.add("E-mail");
prefContctMethods.add("Call");
model.addAttribute("prefContct", prefContctMethods);
List<String> sexType=new ArrayList<String>();
sexType.add("Male");
sexType.add("Female");
model.addAttribute("sexType", sexType);
return "newUser";
}

@RequestMapping(value="saveUser", method=RequestMethod.POST )
public String saveUser(@ModelAttribute User user,Errors errors, Model model)
{
System.out.println(user);
userService.saveUser(user);
model.addAttribute("users", userService.getMockedUsers());
return "allUsers";
}

@RequestMapping("/allUsers")
public String allUsers( Model model)
{
model.addAttribute("users", userService.getMockedUsers());
return "allUsers";
}
}


You can see I have use @Autowired annotations . To support this we have to register the bean UserService it can done by adding following line in to the springFirst-servlet.xml.

<bean id="UserService" class="data.UserService"/>

Our final springFirst-servlet.xml will contains following content.

<?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"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
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-4.2.xsd">

<mvc:annotation-driven/>
<context:component-scan base-package="spring.first.controller"></context:component-scan>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>

<bean id="UserService" class="spring.first.data.UserService"/>
<mvc:resources location="/resources/" mapping="/resources/**"></mvc:resources>
</beans>

So when you access the http://localhost:8080/SpringFirstWeb/userHandling You can see similar interface to below image.


Then when you click on New User You can see similar interface to below image(Note that I have fill the form with sample data).


Final result page will be similar to below image.



We have completed our second Spring tutorial which discussed about Spring Form Handling. You can access the project on following URL Repository https://github.com/NirmalBalasooriya/SpringFormHandling. In future post I will provide more advance features in form handling.