Archive

Archive for May, 2013

Spring MVC – Create JSP/JSTL Composite View (Header, Body and Footer)

May 13, 2013 1 comment

Most of the good websites share similar layout but each page is made of different independent pieces, but always placed in the same position across all the site. The Composite View pattern formalizes this typical use, by allowing to create pages that have a similar layout, in which each section of the page vary in different situations. Generally the layout is know as template and each independent piece is know as subview.

The below figure demonstrates how only the Body/Content section of page changes keeping  both header and footer unchanged.

How Composite View Works Image

This behavior  can be achieved  by using various ready to use frameworks like SiteMesh and Apache Tiles  and they provide  easy integration with Spring MVC framework. But if you don’t want to use these frameworks and one to implement your own hack by overriding Spring’s out of the box solution of JSTLView then you can refer to the following steps:

    1. Setup Spring MVC environment: First setup your Spring MVC development environment and modify the dispatcher-servlet.xml  according to the code mentioned below.
      <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
      
      <property name="viewClass" value="com.myapp.web.view.JstlView" />
      
      <property name="prefix" value="/WEB-INF/views/" />
      
      <property name="suffix" value=".jsp" />
       </bean>
      

      As you can see online.exam.web.view.JstlView is our own custom implementation which forces each page to stay inside the template in other words maintain the layout.

    2. Write custom JSTLView:  This is a simple java class which extends org.springframework.web.servlet.view.InternalResourceView class and overrides renderMergedOutputModel method. The implementation of the class is given below. Also note the Step # 1 and 2 are interchangeable. You may choose to write the  java class first and then configure the WebApplicationContext.
      package com.myapp.web.view;
      
      import java.util.Map;
      
      import javax.servlet.RequestDispatcher;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      
      import org.springframework.web.servlet.view.InternalResourceView;
      
      public class JstlView extends InternalResourceView {
      
       @Override
       protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
      
       // Determine the path for the request dispatcher.
       String dispatcherPath = prepareForRendering(request, response);
      
       // set original view being asked for as a request parameter
       request.setAttribute("partial", dispatcherPath.substring(dispatcherPath.lastIndexOf("/") + 1));
      
      // force everything to be template.jsp
       RequestDispatcher requestDispatcher = request.getRequestDispatcher("/WEB-INF/views/template.jsp");
       requestDispatcher.include(request, response);
      
       }
      
      }
      
    3. Write JSP Pages: The following JSP files provides the details of how this Composite View pattern works. It required three basic JSP files for layout or template implementation namely template.jsp, header.jsp and footer.jsp.  The following code segments showcase each of these.
      <%@ 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">
      <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
      <%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
      <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
      <html>
      <head>
      <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
      <title><spring:message code="app.title.home" /></title>
      </head>
       <body>
       <jsp:include page="header.jsp" />
       <jsp:include page="${partial}" />
       <jsp:include page="footer.jsp" />
       </body>
      </html>
      

      The ${partial} attribute replaced by the actual JSP file as body section.

      <%@ 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">
      <link rel="stylesheet" href="css/style.css" type="text/css">
      </head>
      <body>
      <div id="header">
       <div>
       <div class="logo">
       <a href="#">Online Test</a>
       </div>
       <ul id="navigation">
       <li class="active">
       <a href="home.html">Home</a>
       </li>
       <li>
       <a href="about.html">About</a>
       </li>
       <li>
       <a href="contact.html">Contact</a>
       </li>
       </ul>
       </div>
       </div>
      </body>
      </html>
      
      <%@ 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">
      
      </head>
      <body>
      <div id="footer">
       <div class="clearfix">
       <div id="connect">
       <a href="#" target="_blank" class="facebook"></a>
       <a href="#" target="_blank" class="googleplus"></a>
       <a href="#" target="_blank" class="twitter"></a>
       </div>
       <p>
       © 9999 Online Test. No Rights Reserved.
       </p>
       </div>
       </div>
      </body>
      </html>
      
    4. Write Subview Pages: Once all the template pages are ready body/content pages or subviews to be created. It can be any JSP page you want to display in your site. The below example a sample JSP page.
      <%@ 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">
      <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
      <%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
      <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
      <html>
      <head>
      <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
      </head>
      <body>
      <div id="contents">
       <div id="tagline" class="clearfix">
       <h1>This is my home page</h1>
       </div>
      </div>
      </body>
      </html>
      
    5. Write Spring Controllers to Navigate:  Spring MVC required controllers to process http requests.  A typical spring controller should look  the following:
      package com.myapp.web.controllers;
      
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RequestMethod;
      import org.springframework.web.servlet.ModelAndView;
      
      @Controller
      @RequestMapping("/home")
      public class HomeController {
      
      @RequestMapping(method = RequestMethod.GET)
       public ModelAndView handleRequest() {
      
       return new ModelAndView("home");
       }
      
      }
      

Now the application is ready for initial testing or can build your entire web application based on this layout.