Richard’s Weblog

February 2, 2014

Apache Tiles 3, integration with spring MVC

Filed under: Spring Framework,template system,Web development — Richard @ 6:58 pm
Tags: ,

Introduction

Tiles 3 can be integrated with spring framework version 3.2. In this example I am using spring version 3.2.7. The complete source for this example is available at github. In this example, I build a simple web application using tiles to build a template where I put a header, a footer, a menu and the pages bodies. I will create two pages : home and about.

Dependencies

Here I’m using maven.  To keep it simple I included a dependency to “tiles-extra”, wich is overkill since it contains all sort of librairies I do not need ( such as tiles-velocity, tiles-freemarker etc ).  :

<dependency>
	<groupId>org.apache.tiles</groupId>
	<artifactId>tiles-extras</artifactId>
	<version>${tiles-version}</version>
</dependency>

Configuration

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

	<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/spring/root-context.xml</param-value>
	</context-param>
	
	<!-- Creates the Spring Container shared by all Servlets and Filters -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<!-- Processes application requests -->
	<servlet>
		<servlet-name>appServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
		
	<servlet-mapping>
		<servlet-name>appServlet</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
	
</web-app>

Here the only relevant part for our example is the servlet and servlet-mapping configuration. Specifying “/” as url-pattern tells the server that my appServlet is the default servlet. If no other servlet can serve the request, appServlet will be called. I do this since springMVC can efficiently handle dynamic as well as static content.

servlet-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

	<mvc:annotation-driven />
	<context:component-scan base-package="com.example.springandtiles" />
	
	<!-- Used to serve static resources like css, images and javascript files-->
	<mvc:resources mapping="/resources/**" location="/resources/" />

	<!-- Resolves views selected for rendering by @Controllers to .jsp resources 
		in the /WEB-INF/views directory -->
	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/views/" />
		<property name="suffix" value=".jsp" />
	</bean>

	<!-- Tiles configuration -->

	<bean id="tilesConfigurer"
		class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
		<property name="definitions">
			<list>
				<value>/WEB-INF/tiles/tiles-definitions.xml</value>
			</list>
		</property>
	</bean>

</beans>

I’m telling spring that all my views will be in “/WEB-INF/views”. Also, note the tile configuration, that defines the tiles config file in “/WEB-INF/tiles/tiles-definitions.xml”. Let’s take a look at the template that will be used

The template

A template named “defaultTemplate” will be configured in tiles-definitions.xml. It will be composed of a header, a menu (on the left) and a footer. The body is not yet defined because it will change on every pages.

tiles-definitions.xml

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE tiles-definitions PUBLIC
       "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
       "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
<tiles-definitions>
 
    <definition name="defaultTemplate" template="/WEB-INF/template/default/template.jsp">
        <put-attribute name="header" value="/WEB-INF/template/default/header.jsp" />
        <put-attribute name="menu" value="/WEB-INF/template/default/menu.jsp" />
        <put-attribute name="footer" value="/WEB-INF/template/default/footer.jsp" />
    </definition>
 
</tiles-definitions>

And let’s take a look at each of the defined parts of my template

template.jsp

<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>
<html>
	<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<title>Default tiles template</title>
	<style type="text/css">
	body {
		margin:0px;
		padding:0px;
		height:100%;
		overflow:hidden;
	}

	.page {
 		min-height:100%;
 		position:relative;
	}
	
	.header {
		padding:10px;
		width:100%;
		text-align:center;
	}
	
	.content {
			padding:10px;
			padding-bottom:20px; /* Height of the footer element */
			overflow:hidden;
	}
	
	.menu {
		padding:50px 10px 0px 10px;
		width:200px;
		float:left;
	}

	.body {
		margin:50px 10px 0px 250px;
	}
	
	.footer {
		clear:both;
		position:absolute;
		bottom:0;
		left:0;
		text-align:center;
		width:100%;
		height:20px;
	}
	
	</style>
</head>
<body>
	<div class="page">
		<tiles:insertAttribute name="header" />
		<div class="content">
			<tiles:insertAttribute name="menu" />
			<tiles:insertAttribute name="body" />
		</div>
		<tiles:insertAttribute name="footer" />
	</div>
</body>
</html>

I know, css should be placed in another file and imported :)

header.jsp

<div class="header">I am the header</div>

menu.jsp

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<div class="menu">
Menu
	<ul>
	    <li>
	    	<spring:url value="/home" var="homeUrl" htmlEscape="true"/>
 			<a href="${homeUrl}">Home</a>
 		</li>
	    <li>
	    	<spring:url value="/about" var="aboutUrl" htmlEscape="true"/>
 			<a href="${aboutUrl}">About</a>
 		</li>
	</ul>
</div>

footer.jsp

<div class="footer">I am the Footer !</div>

The Home page

Since this is a view of my application, I put this file in /WEB-INF/views.

/WEB-INF/views/home.jsp

<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>

<tiles:insertDefinition name="defaultTemplate">
	<tiles:putAttribute name="body">



		<div class="body">
			<h1>Home page !</h1>

			<p>The time on the server is ${serverTime}.</p>
			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore
				magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
				consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
				Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</P>
		</div>



	</tiles:putAttribute>
</tiles:insertDefinition>

This page tells tiles that it will use the “defaultTemplate”, and defines directly the page.

Npw let’s take a look at the spring controller for the home page :

/src/main/java/com/example/springandtiles/HomeController.java

package com.example.springandtiles;

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * Handles requests for the application home page.
 */
@Controller
public class HomeController {
	
	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
	
	/**
	 * Simply selects the home view to render by returning its name.
	 */
	@RequestMapping(value = {"/", "/home"}, method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		logger.info("Welcome home! The client locale is {}.", locale);
		
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
		
		String formattedDate = dateFormat.format(date);
		
		model.addAttribute("serverTime", formattedDate );
		
		return "home";
	}
	
}

On the home page, current time is displayed with a lorem ipsum paragraph. Boring, but simple :)

The About page

/WEB-INF/views/about.jsp

<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>

<tiles:insertDefinition name="defaultTemplate">
	<tiles:putAttribute name="body">



		<div class="body">
			<h1>About page !</h1>

			<p>This is a simple example of Tiles 3 integration with Spring Framework.</p>
			<p>Uses Tiles 3.0.3 and springframework 3.2.7.</P>
		</div>



	</tiles:putAttribute>
</tiles:insertDefinition>

And again, let’s look at the controller for that page

/src/main/java/com/example/springandtiles/AboutController.java

package com.example.springandtiles;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * Handles requests for the application about page.
 */
@Controller
public class AboutController {
	
	private static final Logger logger = LoggerFactory.getLogger(AboutController.class);
	
	@RequestMapping(value = "/about", method = RequestMethod.GET)
	public String about(Model model) {
		logger.info("About page !");
		
		return "about";
	}
	
}

Starting my project in tomcat gives me a screen that looks like this :
tiles3springintegrationexample

That’s all for this example, hope it will be useful for you.

Advertisements

16 Comments »

  1. […] UPDATE : I’ve written another example but using Tiles 3.0.3 and SpringMVC 3.2.7. See here […]

    Pingback by Apache Tiles 2, integration with Spring-MVC | Richard's Weblog — February 2, 2014 @ 7:14 pm | Reply

  2. Thank you for this tutorial, I have a question, how if for example in the about page you have a form to submit and the result is another page ?
    Thanks, your help is appreciated.

    Comment by Majid Lotfi — February 24, 2014 @ 10:44 pm | Reply

    • Ok, Say we have a form like this in the about page:

      <form action="${pageContext.request.contextPath}/about" method="POST" >
          <input name="data" value="postMe"/>
          <input type="submit"/>
      </form>
      

      Then, in AboutController I would handle the form like this :

      @RequestMapping(value = "/about", method = RequestMethod.POST)
      public ModelAndView postHandler(@RequestParam(value="data") String data) {
          return new ModelAndView("otherPage", "data", data );
      }
      

      And finally, I’d havve to add the “otherPage”, so create otherPage.jsp in /WEB-INF/views :

      <%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
      <tiles:insertDefinition name="defaultTemplate">
      	<tiles:putAttribute name="body">
      		<div class="body">
      			<h1>Other page !</h1>
      			<p>You posted : ${data}</P>
      		</div>
      	</tiles:putAttribute>
      </tiles:insertDefinition>
      

      Hope this help :)

      Comment by Richard — February 25, 2014 @ 12:31 am | Reply

      • Thanks brother, I appreciate your help.

        Comment by Majid Lotfi — February 25, 2014 @ 12:05 pm | Reply

  3. hi, your configuration looks different because you are still using InternalResourceViewResolver. However, it works and I like it.
    any comments on this type of configuration?

    http://tech.finn.no/2012/07/25/the-ultimate-view-tiles-3/

    thanks, have a good day.

    Comment by tiger — February 27, 2014 @ 9:15 pm | Reply

  4. Nice tutorial! Works!
    Thanks!

    Comment by Mirco Gatz — March 25, 2014 @ 6:33 am | Reply

  5. Nice tutorial.
    Thanks

    Comment by Pham Thai Thinh — April 21, 2014 @ 10:44 pm | Reply

  6. Thanks! Very good article.

    Comment by Thoai Nguyen — September 22, 2014 @ 4:13 am | Reply

  7. Thanks for the tutorial :) just one thing, where’s should I put the root-content.xml file? is it necessary?

    Comment by Gustavo Lara — November 5, 2014 @ 1:21 am | Reply

  8. Great tutorial. Thank you so much!

    Comment by John Feeney — November 27, 2014 @ 7:43 pm | Reply

  9. “Boring” yet very easy to understand. Such a good article. Thanks!

    Comment by Kurtz — December 16, 2014 @ 3:07 am | Reply

  10. […] but is that a good practice? isn’t there any alternative as I am using tiles? This tutorial suggested to have separate controllers but I am not sure if that would be an optimal solution. As […]

    Pingback by How to handle addressing to static pages in Spring MVC | DL-UAT — March 18, 2015 @ 8:28 am | Reply

  11. Reblogged this on HelpEzee.

    Comment by pampanasatyanarayana — April 10, 2015 @ 5:20 am | Reply

  12. Thanks <3

    Comment by Excelent Tutorial — August 6, 2015 @ 3:06 pm | Reply

  13. Thank you Thank Thank you! I am learning the Spring MVC and your example of invaluable help in setting up an example project.

    Comment by Andy — November 19, 2015 @ 8:26 pm | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: