lishman levelup
«previous  next»


Getting Started
Form Processing
IoC Container
Hibernate ORM



Spring Web MVC Quick Start


Get up and running with Spring Web MVC.

Follow the instructions below and the application structure should look like this:

Application Structure for Spring MVC form processing

1. Download

Download and install the Spring Framework.

2. Country.java

Create the Country class.
package levelup.world.domain;

import java.util.Date;

public class Country {

  private Integer id;
  private String name;
  private Integer area;
  private Long population;
  private Date populationLastUpdated;
  private String currency;

  public Country () {}

  public Country (Integer id,
                  String name,
                  Integer area,
                  Long population,
                  Date populationLastUpdated,
                  String currency) {
    setId(id);
    setName(name);
    setArea(area);
    setPopulation(population);
    setPopulationLastUpdated(populationLastUpdated);
    setCurrency(currency);
  }

  public boolean isNew() {
    return id==null;
  }

  public void setId(Integer id) {
    this.id = id;
  }

  public Integer getId() {
    return id;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getName() {
    return name;
  }

  public void setArea(Integer area) {
    this.area = area;
  }

  public Integer getArea() {
    return area;
  }

  public void setPopulation(Long population) {
    this.population = population;
  }

  public Long getPopulation() {
    return population;
  }

  public void setPopulationLastUpdated(Date populationLastUpdated) {
    this.populationLastUpdated = populationLastUpdated;
  }

  public Date getPopulationLastUpdated() {
    return populationLastUpdated;
  }

  public void setCurrency(String currency) {
    this.currency = currency;
  }

  public String getCurrency() {
    return currency;
  }

}

3. WorldService.java

Create the WorldService interface.
package levelup.world.domain.service;

import java.util.Collection;
import levelup.world.domain.Country;

public interface WorldService {

  public Collection<Country> getAllCountries();

  public Country getCountryById(int countryId);

  public Country getCountryByName(String countryName);

  public void saveCountry(Country country);

  public void deleteCountry(Country country);

}

4. MockWorldService.java

Create the MockWorldService class.
package levelup.world.domain.service;

import java.text.ParseException;
import java.text.SimpleDateFormat;

import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import levelup.world.domain.Country;


public class MockWorldService implements WorldService {

  private static Map<Integer, Country> countries = new HashMap<Integer, Country>();
  private static int nextCountryId = 200;

  static {
    countries.put(14,   new Country(14,   "Germany",      137847,   82046000L,  parseDate("30-nov-2008"),   "Euro"));
    countries.put(48,   new Country(48,   "Ghana",        92098,    23837000L,  null,                       "Cedi"));
    countries.put(53,   new Country(53,   "Australia",    2966200,  21884000L,  parseDate("04-sep-2009"),   "Australian Dollar"));
    countries.put(73,   new Country(73,   "Greece",       50949,    11257285L,  parseDate("1-jan-2009"),    "Euro"));
    countries.put(122,  new Country(122,  "Georgia",      26900,    4382100L,   parseDate("1-jan-2009"),    "Lari"));
    countries.put(123,  new Country(123,  "New Zealand",  104454,   4320300L,   parseDate("4-sep-2009"),    "New Zealand Dollar"));
    countries.put(147,  new Country(147,  "Gambia",       4361,     1705000L,   null,                       "Dalasi"));
    countries.put(149,  new Country(149,  "Gabon",        103347,   1475000L,   null,                       "CFA franc"));
  }

  private static Date parseDate(String textDate) {
    try {
      return new SimpleDateFormat("dd-MMM-yyyy").parse(textDate);
    } catch (ParseException e) {
      e.printStackTrace();
      throw new RuntimeException(e);
    }
  }

  public Collection<Country> getAllCountries() {
    return countries.values();
  }

  public Country getCountryById(int countryId) {
    // Returns a new object and not just a reference
    // to an object in the collection.
    Country country = countries.get(countryId);
    return new Country(country.getId(),
                       country.getName(),
                       country.getArea(),
                       country.getPopulation(),
                       country.getPopulationLastUpdated(),
                       country.getCurrency());
  }

  public Country getCountryByName(String countryName) {
    for (Country country : countries.values()) {
      if (country.getName().toLowerCase().equals(countryName.toLowerCase())) {
        return country;
      }
    }
    return null;
  }

  public void saveCountry(Country country) {
    if (country.isNew()) {
      nextCountryId++;
      country.setId(nextCountryId);
      countries.put(nextCountryId, country);
    } else {
      countries.put(country.getId(), country);
    }
  }

  public void deleteCountry(Country country) {
    countries.remove(country.getId());
  }

}

5. CountryController.java

Create the CountryController class.
package levelup.world.web;

import java.util.Collection;

import levelup.world.domain.Country;
import levelup.world.domain.service.MockWorldService;
import levelup.world.domain.service.WorldService;

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

@Controller
public class CountryController {

  private WorldService worldService = new MockWorldService();

  @RequestMapping("/countryList.html")
  @ModelAttribute("countries")
  public Collection<Country> getCountries() {
    return worldService.getAllCountries();
  }

  @RequestMapping("/countryDetails.html")
  public Country getCountry(@RequestParam(value="id", required=true) int countryId) {
    return worldService.getCountryById(countryId);
  }
}

6. countryList.jsp

Create the countryList.jsp file.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>

<html>
  <head>
    <link rel="stylesheet" href="./css/world.css" type="text/css"/>
    <title>
      <spring:message code="country.plural"/>
    </title>
  </head>
  <body>
    <h1><spring:message code="application.name"/></h1>

    <table class="silver" width="150">
      <tr>
        <th><spring:message code="country.plural"/></th>
      </tr>
      <c:forEach items="${countries}" var="country">
        <tr>
          <td>
            <a href="countryDetails.html?id=${country.id}">
              ${country.name}
            </a>
          </td>
        </tr>
      </c:forEach>
    </table>

  </body>
</html>

7. countryDetails.jsp

Create the countryDetails.jsp file.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>

<html>
  <head>
    <link rel="stylesheet" href="./css/world.css" type="text/css"/>
    <title>
      <spring:message code="country.details"/>
    </title>
  </head>
  <body>
    <h1><spring:message code="application.name"/></h1>
    <table class="silver" width="260">
      <tr>
        <th colspan=2><spring:message code="country.details"/></th>
      </tr>
      <tr>
        <td><spring:message code="country.name"/></td>
        <td>${country.name}</td>
      </tr>
      <tr>
        <td><spring:message code="country.area"/></td>
        <td><fmt:formatNumber type="number" value="${country.area}" /></td>
      </tr>
      <tr>
        <td><spring:message code="country.population"/></td>
        <td><fmt:formatNumber type="number" value="${country.population}" /></td>
      </tr>
      <tr>
        <td><spring:message code="country.updatedOn"/></td>
        <td><fmt:formatDate value="${country.populationLastUpdated}"/></td>
      </tr>
      <tr>
        <td><spring:message code="country.currency"/></td>
        <td>${country.currency}</td>
      </tr>
    </table>
    <a href="countryList.html">
      &lt;&lt;<spring:message code="navigation.back"/>
    </a>
  </body>
</html>

8. world.css

Create the world.css file.
h1 {
  font-family: Verdana, Geneva, sans-serif;
  font-size:1.1em;
  font-weight:normal;
  color:SeaGreen;
  margin: 1em 1em 1em 1em;
}

a {
  color:DarkSlateGray;
  font-weight:normal;
  text-decoration:none;
}

a:hover {
  color:OrangeRed;
  font-weight: normal;
  text-decoration:none;
}

table.silver {
  margin: 0em 0em 1em 2em;
  background: WhiteSmoke;
  border-collapse: collapse;
}

table.silver th {
  color:DarkSlateGray;
  background: Gainsboro;
  text-align: left;
}

table.silver th, table.silver td {
  border: 1px Silver solid;
  padding: 0.2em;
}

.errors {
  color: Red;
  font-weight: bold;
}

9. web.xml

Create the web.xml file.
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

  <!-- Register a servlet that despatches requests to registered controllers  -->
  <servlet>
    <servlet-name>world</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <!--  Send all .html files to the Spring dispatcher servlet -->
  <servlet-mapping>
    <servlet-name>world</servlet-name>
    <url-pattern>*.html</url-pattern>
  </servlet-mapping>

  <!-- Define the web application entry point -->
  <welcome-file-list>
    <welcome-file>countryList.html</welcome-file>
  </welcome-file-list>

</web-app>

10. world-servlet.xml

Create the world-servlet.xml file.
<?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:p="http://www.springframework.org/schema/p"
          xmlns:context="http://www.springframework.org/schema/context"
          xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">

  <!-- Auto-detect controllers in this package -->
  <context:component-scan base-package="levelup.world.web"/>

  <!--  Prepend /WEB-INF/jsp/ and append .jsp to the view name  -->
  <bean id="viewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/jsp/"/>
    <property name="suffix" value=".jsp"/>
  </bean>

  <!-- Access resource bundles with the specified basename -->
  <bean id="messageSource"
    class="org.springframework.context.support.ReloadableResourceBundleMessageSource"
    p:basename="/WEB-INF/messages"/>

</beans>

11. messages.properties

Create the messages.properties file.
application.name=hello world

navigation.back=Back

country.plural=Countries
country.details=Country Details
country.name=Name
country.area=Area
country.population=Population
country.updatedOn=Last Updated
country.currency=Currency

12. messages_en.properties

Create the messages_en.properties file.
application.name=hello world

#navigation.back=Back falls back to messages.properties

country.plural=Countries
country.details=Country Details
country.name=Name
country.area=Area
country.population=Population
country.updatedOn=Last Updated
country.currency=Currency

13. messages_fr.properties

Create the messages_fr.properties file.
application.name=bonjour monde

navigation.back=Retournez

country.plural=Pays
country.details=Détails de pays
country.name=Nom
country.area=Taille
country.population=Population
country.updatedOn=Dernier mis à jour
country.currency=Devise

Deploy the application and display the countryList.html page.
»