Spring Framework Part II-MVC

[article] [edit page] [discussion] [history]

From Humanitarian-FOSS Project Development Site

Spring is a FOSS framework for developing "industrial strength" (i.e., enterprise) applications. Spring is a layered and modular architecture that has various features. Over the course of these tutorials we will look at several of its key functionalities.

Image:Spring framework.gif

In this tutorial we will look at the Spring Web MVC module, which is useful for building user interfaces (UI). This tutorial is based on this very nice tutorial by Alan Sexton. Before beginning this tutorial you should familiarize yourself with the basics of Java web applications because the Spring framework makes use of Java servlets, Java Server Pages (JSPs), and the Java Standard Tag Library (JSTL).

Contents

Model View Controller

Model-View-Controller (MVC) is a software engineering pattern used in designing web applications. Its chief advantage is the separation of the program's control logic (sometimes called business logic) from its presentation or user interface. Before beginning this tutorial you should familiarize yourself with some of the general MVC concepts. There is also this nice article on GUIs by Martin Fowler.

As we will see, in the Spring framework, JSPs and JSTLs are used to implement the views and servlets are used to implement controllers. However much of the work of building these elements has been moved into the Spring framework. Programming in the Spring framework means that we will describe what these elements do rather how they do them.

The application we describe is a simple welcome application. When you request it through the browser, the following page will appear:

Image:sprmvc.jpg

The View

The view for our simple application will be handled by the JSP (with path name 'WEB-INF/jsp/home.jsp'):

<%@ page contentType="text/html;charset=UTF-8" language="java" %>    
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>         (1)

<html>
  <head><title>Greeting</title></head>
  <body>
    <h2><c:out value="${message}"/></h2>                             (2)
  </body>
</html>

As we already know, line (1) associates the JSP with the Java tag library (JSTL). That c.out statement on line (2) produces the message that we observed in the above screen shot. The ${message} part retrieves the value of the message variable. This variable may be defined anywhere within the scope of application. That is, in might be a page variable or session variable or part of a HTTP request and so on.

The Controller

The messsage variable in this example is declared in the controller (with path name src/HomeController.java):

import org.springframework.web.servlet.mvc.Controller;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HomeController implements Controller                    (1)
{
    private String greeting;

    public ModelAndView handleRequest(HttpServletRequest request,    (2)
                                      HttpServletResponse response)
            throws Exception
    {
        String s = greeting +
                   ": the date and time is now " +
                   Calendar.getInstance().getTime() ;
        return new ModelAndView("home", "message", s);               (3)
    }

    public void setGreeting(String greeting)
    {
        this.greeting = greeting;
    }
}

As you can see in line (1), the controller part of MVC for this example is implemented by the HomeController class, which implements the Controller interface. Spring not only provides the Controller interface. It also provides many pre-defined classes that implement the interface. So there are many ways to implement an applications control component besides this simple example. Note the setGreeting() method, which is needed so that the greeting variable can be set by a bean.

Flow of Control

When a page is requested in the Spring framework, the built-in (and hidden) DispatcherServlet fields the request and directs it to one of the application's controllers, according to directives laid out in an XML file (see below). There is typically one controller per request.

In line (2), the handleRequest() method replaces the doGet() and doPut() Java servlet methods. This again is an example of the kinds of details--i.e., the submission protocol--that are handled (and hidden) by the Spring framework.

In line (3), the controller is returning a single ModelAndView object that contains the information that will be displayed (the model) and the view that will display it. In this case, the model is the String s, a concatenation of the greeting plus the time of day. The view is the JSP page we saw above, specified as home here. The message parameter provides the link betwen the view and the model (as we shall see).

The Model

In this very simple example, the model is simply the welcome message--the third argument in the ModelAndView() constructor. As we will see, the value of the message itself is set using a Java bean.

Stitching it Together

The relationships between model, view, and controller are managed by the servlet specifiation, with path name WEB-INF/controller-servlet.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
    <bean name="/welcome/home.html"                                  (1)
          class="HomeController">
        <property name="greeting">
            <value>
                Welcome to Spring MVC
            </value>
        </property>
    </bean>

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

    </bean>
</beans>

As you can see, the first bean (1) assigns the string "Welcome to Spring MVC" to the greeting variable. We saw this in the previous MVC tutorial.

The second bean (2) describes how to resolve the view mentioned in the ModelAndView object that we saw in the HomeController class. Thus it takes the home argument in ModelAndView('home', 'message', s) and converts it into the following path to a JSP page: /WEB-INF/jsp/home.jsp.

The final piece to the application is the web.xml file (at path WEB-INF/web.xml):

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
    <servlet>                          (1)
        <servlet-name>
            controller
        </servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <load-on-startup>
            1
        </load-on-startup>
    </servlet>

    <servlet-mapping>                  (2)
        <servlet-name>
            controller
        </servlet-name>
        <url-pattern>
            *.html
        </url-pattern>
    </servlet-mapping>
</web-app>

Note that the servlet (1) is associated with a built-in Spring class, org.springframework.web.servlet.DispatcherServlet. As we mentioned, the DispatcherServlet will forward requests for /welcome/home.html to the HomeController object. The servlet mapping tag (2) specifies that URLs of the form *.html will be handled by the DispatcherServlet.

Libraries

http://www.cs.trincoll.edu/~ram/sprmvc_libs.zip


Directory Structure

In your Tomcat webapps folder, create the following directory structure for this webapp named sprmvc:


WEB-INF:
total 32
drwxr-xr-x   3 blah  blah  102 Jun  3 20:55 classes
-rw-r--r--   1 blah  blah  684 Jun 11 08:06 controller-servlet.xml
drwxr-xr-x   5 blah  blah  170 Jun  5 16:56 jsp
drwxr-xr-x  10 blah  blah  340 Jun  3 21:20 lib
-rw-r--r--   1 blah  blah  533 Jun  4 22:48 web.xml

WEB-INF/classes:
total 8
-rw-r--r--  1 blah  blah  1166 Jun 11 08:16 HomeController.class

WEB-INF/jsp:
total 24
-rw-r--r--  1 blah  blah  301 Jun  3 20:51 home.jsp

WEB-INF/lib:
total 10688
-rw-r--r--  1 blah  blah    38015 Jun  3 20:54 commons-logging.jar
-rwxr-xr-x  1 blah  blah    16905 Jun  3 20:54 jstl.jar
-rw-r--r--  1 blah  blah    97693 Jun  3 20:54 servlet-api.jar
-rw-r--r--  1 blah  blah  2832933 Jun  3 21:20 spring-2.5.1.jar
-rwxr-xr-x  1 blah  blah   118890 Jun  3 20:54 spring-web.jar
-rwxr-xr-x  1 blah  blah   385822 Jun  3 21:21 spring-webmvc.jar
-rw-r--r--  1 blah  blah  1669573 Jun  3 20:54 spring.jar
-rwxr-xr-x  1 blah  blah   293750 Jun  3 20:54 standard.jar

src:
total 16
-rw-r--r--  1 blah  blah  893 Jun 11 08:16 HomeController.java
-rw-r--r--  1 blah  blah  893 Jun 11 08:12 HomeController.java~


Compiling

Here's the javac command:

javac -classpath ../WEB-INF/lib/servlet-api.jar:../WEB-INF/lib/spring-webmvc.jar:\
../WEB-INF/lib/spring.jar:../WEB-INF/lib/spring-web.jar:\
../WEB-INF/lib/standard.jar:../WEB-INF/lib/commons-logging.jar:\
../WEB-INF/lib/jstl.jar:.  -d ../WEB-INF/classes/ HomeController.java

Exercises

  • Try changing the following elements of this application.
    • Change the main URL to something other than /welcome/home.html, e.g., say hello.html.
    • Change the name of the view to welcome and map it to a file named welcome.jsp.

References

Personal tools