Search This Blog

Sunday 4 November 2012

Basic MVC application in Spring

Spring provides support for MVC based web application development. I decided to create a very basic application involving a simple HTML page and a JSP page.
I created a simple dynamic web project using eclipse:
This implementation uses zero annotations and simply attempts to develop a very basic  MVC application focusing on the actual flow of control within Spring.
The first step is to define the DispatcherServlet. Spring's web support is built around the front controller pattern. This requires the definition of a single servlet which receives all requests and then delegates the responsibility of processing theses requests to appropriate controllers. In Spring we have the front controller servlet predefined as org.springframework.web.servlet.DispatcherServlet.
We simply need to configure it in our web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xmlns="http://java.sun.com/xml/ns/javaee" 
   xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
         http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
   version="3.0">
  <display-name>SpringMVCMinimal</display-name>
  
  <servlet>
      <servlet-name>springDispatcher</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  </servlet>
  
  <servlet-mapping>
        <servlet-name>springDispatcher</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
  
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
</web-app>
We have defined that all requests ending with .do are redirected to the servlet.
When the servlet container loads the DispatcherServlet it
  1. executes the init() method as a part of Servlet lifecycle. The DispatcherServlet inherits its implementation from org.springframework.web.servlet.HttpServletBean. The call of execution is made to the abstract method initServletBean()
  2. the abstract method is implemented by org.springframework.web.servlet.FrameworkServlet. The method is responsible for loading the WebApplicationContext for this application. (via the initWebApplicationContext() method.
  3. the WebApplicationContext is loaded via an XML file with name as <dispatcher servlet name>-servlet.xml. In this case springDispatcher-servlet.xml.
The hierarchy is as below:
Consider the XML configuration file:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://www.springframework.org/schema/beans"     
    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">

      <bean id="urlMapping"
        class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <value>
                /**/anything.do=defaultController
            </value>
        </property>
    </bean>             
        
    <bean id="defaultController" class="com.mvc.controller.WelcomeController"></bean>

    <bean id="viewResolver"
        class=" org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="suffix">
            <value>.jsp</value>
        </property>
    </bean>                  
</beans>
The first part is the Controller. In this case we have created a simple controller bean by name "defaultController".
public class WelcomeController implements Controller {

    @Override
    public ModelAndView handleRequest(final HttpServletRequest request,
            final HttpServletResponse response) throws Exception {
        ModelAndView modelAndView = null;
        modelAndView = new ModelAndView("welcome");
        return modelAndView;
    }

}
The Controller implements the handleRequest method that receives a request and response object. The controller can process the request and generate a suitable response. It then forwards the response to a suitable view which will be displayed.(Implementing the controller is not needed anymore with the arrival of annotations.) But how does the controller decide which view ?
This is where the ModelAndView return value comes into picture. The class is a holder for both Model and View in the web MVC framework. It returns to the controller both model and view in a single return value.
In the above code we do not have any model data. We simply return the view to be used.
The Servlet now needs to decode the view. For that I used a ViewResolver. The job of the view-resolver is to convert a view name into an actual view.
As our view is a jsp file , I used a simple InternalResourceViewResolver class that converts welcome into welcome.jsp.
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
      "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
        <title>Spring MVC Minimal</title>
    </head>
    <body>
        This is the minimal view as JSP
    </body>
</html>
This still leaves one question open. How does the Servlet select the controller to use ?
For this we defined a UrlMapping object. We specified in our xml file that requests ending in "anything.do" must be sent to the bean with name "defaultController".
We shall look into the details of this object in later posts.
The last thing was the welcome page which simply redirects to the controller
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
      "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <title>Spring MVC Minimal</title>
    </head>
    <body>
        Redirect application follow from 
        <a href="/SpringMVCMinimal/anything.do">here</a>
    </body>
</html>
On deploying the application:
The Welcome page
In hitting the link we can see the JSP output:
The jsp after being resolved by a View Resolver
Thus the steps that occur when a request is made is as below:
  1. Request received by DispatcherServlet
  2. Dispatcher servlet identifies the controller to delegate the request to.
  3. Controller on receiving request processes it and generates the model objects to be sent as data and also the view to display the data.
  4. DispatcherServlet identifies the view to use based on returned value from Controller.
  5. It passes the models to the view which is then finally sent back as response to the client.

2 comments:

  1. Really helpful content.
    Thanks

    ReplyDelete
  2. Thanks a lot for sharing your knowledge. Keep up the great work!

    ReplyDelete