Spring MVC 4 - Form handling example

Posted on April 16, 2017


In this post, we will show you how to create and submit a simple from in Spring MVC application.  

Tools and technologies used-

  • Spring 4.3.7.RELEASE
  • Eclipse Neon.3
  • Maven 3.3.9
  • JavaSE 1.8
  • Apache Tomcat  7.0.47 (Embedded)

In this example, we will use the @ModelAttribute and @RequestMapping annotations to handler the form data. So let us proceed to write a simple Spring MVC application for user registration.

Project structure

Review the following web project structure.

SpringMVC-FormHandling1.png

Jar dependencies

Open your pom.xml file and write the following code in it.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.boraji.tutorial.spring</groupId>
  <artifactId>spring-mvc-form-handling-example</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <properties>
    <failOnMissingWebXml>false</failOnMissingWebXml>
  </properties>
  <dependencies>
    <!-- Spring MVC Dependency -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>4.3.7.RELEASE</version>
    </dependency>

    <!-- JSTL Dependency -->
    <dependency>
      <groupId>javax.servlet.jsp.jstl</groupId>
      <artifactId>javax.servlet.jsp.jstl-api</artifactId>
      <version>1.2.1</version>
    </dependency>
    <dependency>
      <groupId>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
    </dependency>

    <!-- Servlet Dependency -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>

    <!-- JSP Dependency -->
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>javax.servlet.jsp-api</artifactId>
      <version>2.3.1</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>

  <build>
    <sourceDirectory>src/main/java</sourceDirectory>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.5.1</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>

      <!-- Embedded Apache Tomcat required for testing war -->
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.2</version>
        <configuration>
          <path>/</path>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

Model Class

Create User.java class under com.boraji.tutorial.spring.model package.

It will be used for binding from data to the model and exposing model data to views.

User.java

package com.boraji.tutorial.spring.model;

public class User {
   private String firstName;
   private String lastName;
   private String username;
   private String password;
   private String email;

  // Getter and Setter methods
  //....
}

Controller class

Create a @Controller class under com.boraji.tutorial.spring.controller package and write the following code in it.

UserController.java

package com.boraji.tutorial.spring.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;

import com.boraji.tutorial.spring.model.User;

/**
 * @author imssbora
 */
@Controller
public class UserController {

   /*
    * Create new user object for empty from
    */
   
   @ModelAttribute("user")
   public User setUpUserForm() {
      return new User();
   }

   /*
    * Open new registration form
    */
   @GetMapping("/")
   public String registration() {
      
      return "registrationForm";
   }

   /*
    *  Save user object
    */
   @PostMapping("/saveUser")
   public String saveUser(@ModelAttribute("user") User user, Model model) {

      // Implement business logic to save user details into a database
      //.....
      
      System.out.println("FirstName : " + user.getFirstName());
      System.out.println("LastName : " + user.getLastName());
      System.out.println("Username : " + user.getUsername());
      System.out.println("Password : " + user.getPassword());
      System.out.println("Email : " + user.getEmail());

      model.addAttribute("message", "User saved successfully.");

      return "registrationSuccess";
   }
}

 

JSP Views

Create registrationForm.jsp file under src\main\webapp\WEB-INF\views folder to display user registration from.

The <from:from> and <from:input> tags (String-from JSP tag libriray) are rendered to the html <from> and <input> tags respectively.

registrationForm.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
   pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>BORAJI.COM</title>
</head>
<body>
   <h1>User Registration Form</h1>
   <hr />

   <form:form action="saveUser" method="post" modelAttribute="user">
      <table>
         <tr>
            <td>First Name</td>
            <td><form:input path="firstName" /></td>
         </tr>
         <tr>
            <td>Last Name</td>
            <td><form:input path="lastName" /></td>
         </tr>
         <tr>
            <td>Username</td>
            <td><form:input path="username" /></td>
         </tr>
         <tr>
            <td>Password</td>
            <td><form:password path="password" /></td>
         </tr>
         <tr>
            <td>Email</td>
            <td><form:input path="email" /></td>
         </tr>
         <tr>
            <td></td>
            <td><form:button>Submit</form:button></td>
         </tr>
      </table>
   </form:form>

</body>
</html>

Create another registrationSuccess.jsp file under src\main\webapp\WEB-INF\views folder to display the success/failure message of user registration.

registrationSuccess.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
   pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>BORAJI.COM</title>
</head>
<body>
   <h1>${message}</h1>
   <hr />

   <table>
      <tr>
         <td>First Name : ${user.firstName}</td>
      </tr>
      <tr>
         <td>Last Name : ${user.lastName}</td>
      </tr>
      <tr>
         <td>Username ${user.username}</td>
      </tr>
      <tr>
         <td>Email : ${user.email}</td>
      </tr>
   </table>
</body>
</html>

Spring configuration

Create a web @Configuration class annotated with @EnableWebMvc and @ComponentScan as follows.

WebConfig.java

package com.boraji.tutorial.spring.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

/**
 * @author imssbora
 */

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "com.boraji.tutorial.spring.controller" })
public class WebConfig extends WebMvcConfigurerAdapter {

   @Bean
   public InternalResourceViewResolver resolver() {
      InternalResourceViewResolver resolver = new InternalResourceViewResolver();
      resolver.setViewClass(JstlView.class);
      resolver.setPrefix("/WEB-INF/views/");
      resolver.setSuffix(".jsp");
      return resolver;
   }
}

The @EnableWebMvc enables default Spring MVC configuration and provides the functionality equivalent to <mvc:annotation-driven/> element in XML based configuration.

The @ComponentScan scans the stereotype annotations (@Controller@Service etc...) in a package specified by basePackages attribute.

 

Servlet container initialization

Create a container initializer class by extending the AbstractAnnotationConfigDispatcherServletInitializer class as follows.

MyWebAppInitializer.java

package com.boraji.tutorial.spring.config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

/**
 * @author imssbora
 */
public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

   @Override
   protected Class<?>[] getRootConfigClasses() {
      return new Class[] {};
   }

   @Override
   protected Class<?>[] getServletConfigClasses() {
      return new Class[] { WebConfig.class };
   }

   @Override
   protected String[] getServletMappings() {
      return new String[] { "/" };
   }
}

 

Build + Deploy + Run application

Use the following maven commands to build, deploy and run embedded Tomcat server.

mvn clean install  (This command triggers war packaging)

mvn tomcat7:run (This command run embedded tomcat and deploy war file automatically)

You can refer this link to learn how to run the above commands in Eclipse IDE.

 

Type the following URLs in browser's address bar and see output…

http://localhost:8080/

SpringMVC-FormHandling2.png

Click on Submit button to save the from data.

SpringMVC-FormHandling3.png

Download Sources