Saturday, April 18, 2020

Spring MVC example – display, validate and submit form (part 1)

In any spring web mvc application, we often have to deal with forms. Application first displays a form and the user fills this form and submits it to server. At server, application needs to capture the form inputs and process the inputs (e.g. store in database) and return a success view. In this spring mvc example, we will learn to display forms and then we will learn to process submitted form fields.
In this example, we are creating an employee management module with add employee feature. It will have following capabilities:
  1. Display empty form on initial page load
  2. Display error messages if form is submitted with empty field
  3. After successful form submit, redirect to another screen with success message


Spring MVC Form Example - Blank Form
Spring MVC Form Example – Blank Form



Table of Contents

1. Create model data
2. Create form views
3. Create form controller
4. Form validation
5. Demo
Let’s start adding application components one by one and noting down things which matter.

1. Spring MVC model data

For this example application, EmployeeVO class is used as model. It will hold the data which view will use to render and post back to controller.
EmployeeVO.java
package com.howtodoinjava.demo.model;
import java.io.Serializable;
public class EmployeeVO implements Serializable
{
    private static final long serialVersionUID = 1L;
    private Integer id;
    private String firstName;
    private String lastName;
    private String email;
    //Getters and Setters
    @Override
    public String toString() {
        return "EmployeeVO [id=" + id + ", firstName=" + firstName
                + ", lastName=" + lastName + ", email=" + email + "]";
    }
}

2. Spring MVC form views

This application uses two views i.e. one for displaying form and another for displaying success message.

2.1. Input form view

addEmployee.jsp
<%@ page contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<html>
<head>
    <title>Add Employee Form</title>
</head>
<body>
    <h2><spring:message code="lbl.page" text="Add New Employee" /></h2>
    <br/>
    <form:form method="post" modelAttribute="employee">
        <table>
            <tr>
                <td><spring:message code="lbl.firstName" text="First Name" /></td>
                <td><form:input path="firstName" /></td>
            </tr>
            <tr>
                <td><spring:message code="lbl.lastName" text="Last Name" /></td>
                <td><form:input path="lastName" /></td>
            </tr>
            <tr>
                <td><spring:message code="lbl.email" text="Email Id" /></td>
                <td><form:input path="email" /></td>
            </tr>
            <tr>
                <td colspan="2"><input type="submit" value="Add Employee"/></td>
            </tr>
        </table>
    </form:form>
</body>
</html>
Important Points:
  1. The Spring <form:form> tag declares two attributes. The method="post" attribute used to indicate a form performs an HTTP POST request upon submission. And the modelAttribute="employee” attribute used to indicate the form data is bound to a model named employee.
  2. Form’s various <form:input> tags make use of the attribute path to indicate the form’s fields to which they are bind. They show the user the original value of the field, which will either be the bound property value or the value rejected due to a binding error. They must be used inside the <form:form> tag, which defines a form that binds to the modelAttribute by its name.
  3. Finally, you can find the standard HTML tag <input type="submit" /> that generates a ‘Submit’ button and trigger the sending of data to the server, followed by the tag that closes out the form.
Please note that <spring:message> tags are used for displaying field labels for message resource file present in classpath. In our case, content of message resource is as follow:
messages.properties
lbl.page=Add New Employee
lbl.firstName=First Name
lbl.lastName=Last Name
lbl.email=Email Id

2.2. Success page view

addSuccess.jsp
<html>
    <head>
        <title>Add Employee Success</title>
    </head>
    <body>
        Employee has been added successfully.
    </body>
</html>
This file is pretty straight forward and just displays the success message.

3. Spring MVC form controller

A very simple spring mvc controller to handle form submission.
EmployeeController.java
@Controller
@RequestMapping("/employee-module/addNew")
@SessionAttributes("employee")
public class EmployeeController
{
    @Autowired
    EmployeeManager manager;
     
    @RequestMapping(method = RequestMethod.GET)
    public String setupForm(Model model)
    {
         EmployeeVO employeeVO = new EmployeeVO();
         model.addAttribute("employee", employeeVO);
         return "addEmployee";
    }
     
    @RequestMapping(method = RequestMethod.POST)
    public String submitForm(@ModelAttribute("employee") EmployeeVO employeeVO,
                            BindingResult result, SessionStatus status)
    {
        //Store the employee information in database
        //manager.createNewRecord(employeeVO);
         
        //Mark Session Complete
        status.setComplete();
        return "redirect:addNew/success";
    }
     
    @RequestMapping(value = "/success", method = RequestMethod.GET)
    public String success(Model model)
    {
         return "addSuccess";
    }
}
Important Points:
  1. The controller starts by using the standard @Controller annotation, as well as the @RequestMapping annotation that allows access to the controller through the URL http://localhost:8080/springmvcexample/employee-module/addNew
  2. When you enter this URL in your browser, it will send an HTTP GET request to your web application. This in turn triggers the execution of the setupForm method, which is designated to attend this type of request based on its @RequestMapping annotation.
  3. Since it’s possible for a form to contain errors, it can be an inconvenience to lose whatever valid data was already provided by a user on every subsequent submission. To solve this problem, the @SessionAttributes is used to save a employee field to a user’s session, so that any future reference to the employee field is in fact made on the same reference, whether a form is submitted twice or more times.
  4. The setupForm method defines a Model object as an input parameter, which serves to send model data to the view (i.e., the form). Inside the handler method, an empty EmployeeVO object is created that is added as an attribute to the controller’s Model object. Then the controller returns the execution flow to the addEmployee view, which in this case is resolved to addEmployee.jsp which we saw above.
  5. After you have filled in the form fields, submitting the form triggers an HTTP POST request, that in turn invokes the submitForm method. The @ModelAttribute("employee") EmployeeVO employeeVO used to reference the employee object. The BindingResult object that contains newly submitted data by the user. And the SessionStatus object used in case it’s necessary to access a user’s session.
  6. Right before a user is redirected to a success page, we should flush out the session data because now it’s of no use. This is done by calling the setComplete() method on the SessionStatus object.
  7. After creating an employee in database, submitForm method returns a view named redirect:addNew/success. The redirect: prefix in the view name is used to avoid a problem known as duplicate form submission.
When you refresh the web page in the form success view, the form you just submitted is resubmitted again. To avoid this problem, you can apply the post/redirect/get design pattern, which recommends redirecting to another URL after a form submission is handled successfully, instead of returning an HTML page directly.

Continue to (

)


No comments:

Post a Comment

How to DROP SEQUENCE in Oracle?

  Oracle  DROP SEQUENCE   overview The  DROP SEQUENCE  the statement allows you to remove a sequence from the database. Here is the basic sy...