Simple Layouts with JSP in Spring MVC

13 Dec, 2009 · 2 min read · #java #spring

Every web application has elements common to all its pages which are good candidates for re-use. While Spring MVC provides integration with Tiles, it can be an overkill for simple applications and needs using Spring’s client side JS library for AJAX (correct me if I’m wrong).

For most applications, standard JSPs can serve as good layout engine. This post shows how Spring’s handler interceptor can be used to specify a normal JSP file as the layout for a Spring MVC web application.

This interceptor allows you to specify a JSP file containing the layout for the application into which the actual views get plugged. The interceptor takes the actual model and view and replaces the actual view with the layout view’s name and puts the actual view name into the model map to be used by the layout file. If you do not want to include the layout for certain requests (AJAX requests) you can prefix the view name with noLayout:.

The Interceptor

public class LayoutInterceptor extends HandlerInterceptorAdapter {
   private static final String NO_LAYOUT = "noLayout:";

   private String layoutView;

   @Override
   public void postHandle(HttpServletRequest request,
                          HttpServletResponse response,
                          Object handler,
                          ModelAndView modelAndView) throws Exception {

       super.postHandle(request, response, handler, modelAndView);

       String originalView = modelAndView.getViewName();
       if (originalView != null && !originalView.startsWith("redirect:")) {
           includeLayout(modelAndView, originalView);
       }
   }

   private void includeLayout(ModelAndView modelAndView, String originalView) {
       boolean noLayout = originalView.startsWith(NO_LAYOUT);
       String realViewName = noLayout
           ? originalView.substring(NO_LAYOUT.length())
           : originalView;

       if (noLayout) {
           modelAndView.setViewName(realViewName);
       } else {
           modelAndView.addObject("view", realViewName);
           modelAndView.setViewName(layoutView);
       }
   }

   public void setLayoutView(String layoutView) {
       this.layoutView = layoutView;
   }
}

Sample Usage

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
   <property name="interceptors">
       <list>
           <bean id="layoutInterceptor" class="LayoutInterceptor">
               <property name="layoutView" value="layout"></property>
           </bean>
       </list>
   </property>
</bean>

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

With that all the views returned by controllers can be included within the layout JSP by including the following line in WEB-INF/jsp/layout.jsp.

<jsp:include page="/WEB-INF/jsp/${view}.jsp"></jsp:include>

If you liked what you read, consider subscribing to the RSS feed in your favourite feed reader.