Enterprise Java

Spring MVC: form handling vol. 1

Spring MVC is a part of Spring Framework and its main purpose is to make web-development more simple, convenient and easy. interaction with forms is a part of every more or less modern web application. Spring MVC allows you to perform all kinds of activity with forms in a very strict and simple way. In the article you will read the basics of form handling with the help of Spring MVC.

I will use one of my previous tutorials related to Spring MVC as a basis for the example below. I prefer java based configuration, so don’t be surprised that in this tutorial you will also see them. Let’s move to the section where I will point out the main aim of this post.

Spring form handling tutorials:

Main goal

I will show you how to handle form with the help of Spring MVC, how to bound a domain model with a form, how to process the form data and represent it in a view.

Development

Our project will be based on Dynamic Web Project and Maven. It’s a traditional set which I recommend to use for a professional software development. The first steps will refer to the post mentioned earlier in the article. I mean the creation of the project in Eclipse and its conversion into Maven project. Further I will demonstrate you all required files which I need to complete the example.

pom.xml looks like:

<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>EduSprMvc</groupid>
	<artifactid>EduSprMvc</artifactid>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>

	<properties>
		<spring.version>3.1.1.RELEASE</spring.version>
	</properties>

	<dependencies>
		<!-- Spring -->
		<dependency>
			<groupid>org.springframework</groupid>
			<artifactid>spring-context</artifactid>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupid>org.springframework</groupid>
			<artifactid>spring-webmvc</artifactid>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupid>org.springframework</groupid>
			<artifactid>spring-beans</artifactid>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupid>org.springframework</groupid>
			<artifactid>spring-web</artifactid>
			<version>${spring.version}</version>
		</dependency>
		<!-- CGLIB is required to process @Configuration classes -->
		<dependency>
			<groupid>cglib</groupid>
			<artifactid>cglib</artifactid>
			<version>2.2.2</version>
		</dependency>
		<!-- Servlet API, JSTL -->
		<dependency>
			<groupid>javax.servlet</groupid>
			<artifactid>javax.servlet-api</artifactid>
			<version>3.0.1</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupid>jstl</groupid>
			<artifactid>jstl</artifactid>
			<version>1.2</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<artifactid>maven-compiler-plugin</artifactid>
				<version>2.3.2</version>
				<configuration>
					<source>1.7
					<target>1.7</target>
				</configuration>
			</plugin>
		</plugins>
	</build>

</project>

After all dependencies were declared we can proceed to the project configuration. As I mentioned before, I’m going to use annotation based config or as many people like to call it “a programmatic configuration approach”. It’s very convenient in case you want to avoid much of xml coding.

WebAppConfig.java

package com.sprmvc.init;

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.view.JstlView;
import org.springframework.web.servlet.view.UrlBasedViewResolver;

@Configuration
@ComponentScan("com.sprmvc")
@EnableWebMvc
public class WebAppConfig {

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

Initializer.java

package com.sprmvc.init;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

public class Initializer implements WebApplicationInitializer {

	@Override
	public void onStartup(ServletContext servletContext) throws ServletException {

		AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
		ctx.register(WebAppConfig.class);

		ctx.setServletContext(servletContext);	

		Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));
		servlet.addMapping("/");
		servlet.setLoadOnStartup(1);

	}
}

Next I’m going to create a class which will represent a data model bounded with the web form. It’s an important step because in the example I will use not simple html form tags but Spring form tag library.

package com.sprmvc.bean;

public class Person {

	private String firstName;
	private Integer age;

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}
}

Notice that the Person class contains just fields with private access modificators and getters / setters for each field. Getters / setters are required because Spring form tags use them to interact with object fields in the view layer. The main part of the tutorial implies development of the controller and views. So let’s proceed.

package com.sprmvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.sprmvc.bean.Person;

@Controller
public class PersonController {

	@RequestMapping(value="/person-form")
	public ModelAndView personPage() {
		return new ModelAndView("person-page", "person-entity", new Person());
	}

	@RequestMapping(value="/process-person")
	public ModelAndView processPerson(@ModelAttribute Person person) {
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.setViewName("person-result-page");

		modelAndView.addObject("pers", person);

		return modelAndView;
	}	
}

The first method in the controller personPage() is responsible for navigation to the page with the form. Notice that return of the method contains Person() class. It’s required for the correct binding of the form with the domain model.
Now let’s move on to the overview of the Person Form page:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
...
<h1>Person page</h1>
<p>This is Person page</p>
<form:form method="POST" commandname="person-entity" action="process-person.html">
<table>
    <tbody><tr>
        <td><form:label path="firstName">Name:</form:label></td>
        <td><form:input path="firstName"></form:input></td>
    </tr>
    <tr>
        <td><form:label path="age">Age:</form:label></td>
        <td><form:input path="age"></form:input></td>
    </tr>
    <tr>
        <td colspan="2">
            <input value="Submit" type="submit">
        </td>
        <td></td>
        <td></td>
    </tr>
</tbody></table>  
</form:form>
...

Here I want to highlight two valuable moments. The first is the import of the spring form tag library. The second is the parameter commandName=”person-entity”. Its value equals to the value of the return parameter in the controller’s first method. Pay your attention that all labels in the form contain path values absolutely correspond to the Person class fields. Let’s go back to the second method processPerson(@ModelAttribute Person person). In this method I want to underline several moments:

  • The method gets parameter Person object annotated with @ModelAttribute. The annotation defines that the method’s argument (Person person) will refer to an appropriate attribute passed from the form.
  • @RequestMapping(value=”/process-person”) contains the value of the URL which will be processed by the method. The same value I have defined in the person-page.jsp; I mean the form’s attribute action=”process-person.html”.
  • I have specified the name of the person object which I pass to modelAndView object. The vname is “pers”. I will use this name in the person-result.page.jsp to call parameters which I need.
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
...
<h1>Person Result page</h1>
<p>Student's name is ${pers.firstName}. The age is ${pers.age}.
...
</p>

Here everything is simple. I use an expression language to access all needed values of the person object which I get after the second method of the controller processes a request. As the result I get such project structure:

Summary

In this tutorial you have seen how to handle forms using Spring MVC. There are not all possible wayshow you can do it. In the future lessons I will demonstrate the rest variants of form handling. The result of the work you can see below:

spring-mvc-form-handling-result

You can download this project from my DropBox.
 

Reference: Spring MVC: form handling vol. 1 from our JCG partner Alexey Zvolinskiy at the Fruzenshtein’s notes blog.

Alexey Zvolinskiy

Alexey is a test developer with solid experience in automation of web-applications using Java, TestNG and Selenium. He is so much into QA that even after work he provides training courses for junior QA engineers.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Omar Gameel Salem
Omar Gameel Salem
10 years ago

in the form attributes, you are using commandname which gives exception ‘Neither BindingResult nor plain target object for bean name ‘command’ available as request attribute’.

instead you should use commandName (capital N)

Rance Moest
Rance Moest
9 years ago

Using a table for a from is so 1995

Back to top button