When building a new Spring MVC application, I often find it useful to start from a barebones Spring MVC application in which I have already gone through the motions of basic configuration and coding.

This simple example realizes a fully functional, albeit limited, Spring MVC application to serve as a springboard for more advanced Spring MVC applications. The goal is to present a simple form, harvest input from the user, process the input on the server, and present it back to the user.

First, the form backing class is defined:

package com.earldouglas.springmvc.web;

import java.util.List;

public class SimpleForm {

    private String value1;
    private String value2;
    private List<String> value3;

    public String getValue1() {
        return value1;
    }

    public void setValue1(String value1) {
        this.value1 = value1;
    }

    public String getValue2() {
        return value2;
    }

    public void setValue2(String value2) {
        this.value2 = value2;
    }

    public List<String> getValue3() {
        return value3;
    }

    public void setValue3(List<String> value3) {
        this.value3 = value3;
    }
}

SimpleForm is a basic value object with two String properties, one List<String> property, and the applicable getter and setter methods.

Next, the controller that will handle SimpleForm submissions is defined:

package com.earldouglas.springmvc.web;

import java.util.ArrayList;
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;

@Controller
public class SimpleController {

    @ModelAttribute("values")
    public List<String> getSimpleValues() {
        List<String> simpleValues = new ArrayList<String>();
        simpleValues.add("Value A");
        simpleValues.add("Value B");
        simpleValues.add("Value C");
        return simpleValues;
    }
    
    @RequestMapping(value = "/simpleForm", method = RequestMethod.GET)
    public void simpleForm(Model model) {
        model.addAttribute(new SimpleForm());
    }

    @RequestMapping(value = "/simple", method = RequestMethod.GET)
    public String simple() {
        return "redirect:simpleForm";
    }

    @RequestMapping(value = "/simple", method = RequestMethod.POST)
    public void simple(@ModelAttribute SimpleForm simpleForm, Model model) {
        model.addAttribute("value1", simpleForm.getValue1());
        model.addAttribute("value2", simpleForm.getValue2());
        model.addAttribute("value3", simpleForm.getValue3());
        model.addAttribute(simpleForm);
    }
}

There are several things going on here. First, the class is annotated with @Controller to indicate to Spring its function as an MVC controller and its candidacy for component scanning by the Spring container. Next, a method is annotated with @ModelAttribute("values") to make available the given List of Strings to the model by the attribute name values. Next, two methods are defined which handle HTTP requests under different conditions. An HTTP GET request to /simpleForm will be processed by simpleForm(), which simply instantiates a new SimpleForm and puts it on the model. Since no attribute name is specified, by convention it will be available under the attribute name simpleForm. An HTTP POST request to /simple will be processed by simple(), which takes the submitted SimpleForm, puts its three properties on the model under the attribute names value1, value2, and value3, and puts the SimpleForm itself on the model, again by convention under the attribute name simpleForm. An HTTP GET request to /simple will cause an HTTP redirect to /simpleForm, a convenient way to redirect the user when they browse to the wrong URL.

That's all the Java code there is to write. Simple! Next, the views are defined.

simpleForm.jsp:

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<form:form action="simple" modelAttribute="simpleForm">
    <table>
        <tr>
            <td>Value 1:</td>
            <td><form:input path="value1" /></td>
        </tr>
        <tr>
            <td>Value 2:</td>
            <td><form:select path="value2" items="${values}" /></td>
        </tr>
        <tr>
            <td>Value 3:</td>
            <td>
                Check 1: <form:checkbox path="value3" value="check1" /><br />
                Check 2: <form:checkbox path="value3" value="check2" /><br />
                Check 3: <form:checkbox path="value3" value="check3" /><br />
            </td>
        </tr>
        <tr>
            <td></td>
            <td><input type="submit" value="Submit" /></td>
        </tr>
    </table>
</form:form>

simple.jsp:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<table>
    <tr>
        <td>Value 1:</td>
        <td><c:out value="${value1}" /></td>
    </tr>
    <tr>
        <td>Value 2:</td>
        <td><c:out value="${value2}" /></td>
    </tr>
    <tr>
        <td>Value 3:</td>
        <td><c:out value="${value3}" /></td>
    </tr>
</table>
<hr />
<c:import url="simpleForm.jsp" />

simpleForm.jsp uses Spring's form tag library to build a form with a text input for value1, a drop-down selection for value2, and checkboxes for value3. The options for the drop-down selection come from the model attribute values defined earlier as a List of Strings.

simple.jsp displays the model attributes value1, value2, and value3, and also includes the form defined in simpleForm.jsp, so it can both be re-used and demonstrate binding defined values to an view's form.

Finally, the spring configuration is defined:

springmvc-servlet.xml:

<?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/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <mvc:annotation-driven />

    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>

    <context:component-scan base-package="com.earldouglas.example.springmvc.web" />
    
</beans>

The <mvc:annotation-driven /> element tells Spring to create a DefaultAnnotationHandlerMapping bean to set up handling of the @RequestMapping annotations in SimpleController, while the lone bean definition registers a view resolver which looks for JSPs by view name. The SimpleController is picked up by the component-scan, instantiated, and mapped to its applicable requests by the DefaultAnnotationHandlerMapping.

Finally, we have our deployment descriptor:

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    version="2.5">

    <servlet>
        <servlet-name>spring-mvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>spring-mvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

Note that since the DispatcherServlet is named springmvc, by convention the Spring configuration is retrieved from /WEB-INF/springmvc-servlet.xml.