In this post we will integrate ​​Apache Tiles 3​​​ with ​​Spring MVC 4​​, using annotation-based configuration. Apache Tiles is a template based, composite view framework: it allows to reuse page pieces across the application, keeping consistent look and feel. Page layouts in general contains several page-fragments like header,footer, menu & content. In a consistent layout, only content changes between page navigation while other page fragments like header,footer & menu remains fixed most of the time.

 

Tiles allows developers to define these page fragments which can be assembled into a complete pages at runtime.

Spring 4 MVC+Apache Tiles 3 Example_spring


Other interesting posts you may like

 

Following technologies being used:

  • Spring 4.2.6.RELEASE
  • Apache Tiles 3.0.5
  • Maven 3
  • JDK 1.7
  • Tomcat 8.0.21
  • Eclipse MARS.1 Release 4.5.1

Let’s begin.

Step 1: Create the directory structure

Following will be the final project structure:

Spring 4 MVC+Apache Tiles 3 Example_spring_02

Spring 4 MVC+Apache Tiles 3 Example_mvc_03

Let’s now add the content mentioned in above structure explaining each in detail.

Step 2: Update pom.xml to include required dependencies


​<​​​​project​​​ ​​xsi:schemaLocation​​​​=​​​​"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"​

​xmlns​​​​=​​​​"http://maven.apache.org/POM/4.0.0"​​​ ​​xmlns:xsi​​​​=​​​​"http://www.w3.org/2001/XMLSchema-instance"​​​​>​

 

​<​​​​modelVersion​​​​>4.0.0</​​​​modelVersion​​​​>​

​<​​​​groupId​​​​>com.websystique.springmvc</​​​​groupId​​​​>​

​<​​​​artifactId​​​​>Spring4MVCApacheTiles3Example</​​​​artifactId​​​​>​

​<​​​​packaging​​​​>war</​​​​packaging​​​​>​

​<​​​​version​​​​>1.0.0</​​​​version​​​​>​

​<​​​​name​​​​>Spring4MVCApacheTiles3Example</​​​​name​​​​>​

 

​<​​​​properties​​​​>​

​<​​​​springframework.version​​​​>4.2.6.RELEASE</​​​​springframework.version​​​​>​

​<​​​​apachetiles.version​​​​>3.0.5</​​​​apachetiles.version​​​​>​

​</​​​​properties​​​​>​

 

​<​​​​dependencies​​​​>​

​<!-- Spring -->​

​<​​​​dependency​​​​>​

​<​​​​groupId​​​​>org.springframework</​​​​groupId​​​​>​

​<​​​​artifactId​​​​>spring-core</​​​​artifactId​​​​>​

​<​​​​version​​​​>${springframework.version}</​​​​version​​​​>​

​</​​​​dependency​​​​>​

​<​​​​dependency​​​​>​

​<​​​​groupId​​​​>org.springframework</​​​​groupId​​​​>​

​<​​​​artifactId​​​​>spring-web</​​​​artifactId​​​​>​

​<​​​​version​​​​>${springframework.version}</​​​​version​​​​>​

​</​​​​dependency​​​​>​

​<​​​​dependency​​​​>​

​<​​​​groupId​​​​>org.springframework</​​​​groupId​​​​>​

​<​​​​artifactId​​​​>spring-webmvc</​​​​artifactId​​​​>​

​<​​​​version​​​​>${springframework.version}</​​​​version​​​​>​

​</​​​​dependency​​​​>​

​<!-- Apache Tiles -->​

​<​​​​dependency​​​​>​

​<​​​​groupId​​​​>org.apache.tiles</​​​​groupId​​​​>​

​<​​​​artifactId​​​​>tiles-core</​​​​artifactId​​​​>​

​<​​​​version​​​​>${apachetiles.version}</​​​​version​​​​>​

​</​​​​dependency​​​​>​

​<​​​​dependency​​​​>​

​<​​​​groupId​​​​>org.apache.tiles</​​​​groupId​​​​>​

​<​​​​artifactId​​​​>tiles-api</​​​​artifactId​​​​>​

​<​​​​version​​​​>${apachetiles.version}</​​​​version​​​​>​

​</​​​​dependency​​​​>​

​<​​​​dependency​​​​>​

​<​​​​groupId​​​​>org.apache.tiles</​​​​groupId​​​​>​

​<​​​​artifactId​​​​>tiles-servlet</​​​​artifactId​​​​>​

​<​​​​version​​​​>${apachetiles.version}</​​​​version​​​​>​

​</​​​​dependency​​​​>​

​<​​​​dependency​​​​>​

​<​​​​groupId​​​​>org.apache.tiles</​​​​groupId​​​​>​

​<​​​​artifactId​​​​>tiles-jsp</​​​​artifactId​​​​>​

​<​​​​version​​​​>${apachetiles.version}</​​​​version​​​​>​

​</​​​​dependency​​​​>​

 

​<!-- Servlet+JSP+JSTL -->​

​<​​​​dependency​​​​>​

​<​​​​groupId​​​​>javax.servlet</​​​​groupId​​​​>​

​<​​​​artifactId​​​​>javax.servlet-api</​​​​artifactId​​​​>​

​<​​​​version​​​​>3.1.0</​​​​version​​​​>​

​</​​​​dependency​​​​>​

​<​​​​dependency​​​​>​

​<​​​​groupId​​​​>javax.servlet.jsp</​​​​groupId​​​​>​

​<​​​​artifactId​​​​>javax.servlet.jsp-api</​​​​artifactId​​​​>​

​<​​​​version​​​​>2.3.1</​​​​version​​​​>​

​</​​​​dependency​​​​>​

​<​​​​dependency​​​​>​

​<​​​​groupId​​​​>javax.servlet</​​​​groupId​​​​>​

​<​​​​artifactId​​​​>jstl</​​​​artifactId​​​​>​

​<​​​​version​​​​>1.2</​​​​version​​​​>​

​</​​​​dependency​​​​>​

 

​</​​​​dependencies​​​​>​

 

​<​​​​build​​​​>​

​<​​​​pluginManagement​​​​>​

​<​​​​plugins​​​​>​

​<​​​​plugin​​​​>​

​<​​​​groupId​​​​>org.apache.maven.plugins</​​​​groupId​​​​>​

​<​​​​artifactId​​​​>maven-compiler-plugin</​​​​artifactId​​​​>​

​<​​​​version​​​​>3.2</​​​​version​​​​>​

​<​​​​configuration​​​​>​

​<​​​​source​​​​>1.7</​​​​source​​​​>​

​<​​​​target​​​​>1.7</​​​​target​​​​>​

​</​​​​configuration​​​​>​

​</​​​​plugin​​​​>​

​<​​​​plugin​​​​>​

​<​​​​groupId​​​​>org.apache.maven.plugins</​​​​groupId​​​​>​

​<​​​​artifactId​​​​>maven-war-plugin</​​​​artifactId​​​​>​

​<​​​​version​​​​>2.4</​​​​version​​​​>​

​<​​​​configuration​​​​>​

​<​​​​warSourceDirectory​​​​>src/main/webapp</​​​​warSourceDirectory​​​​>​

​<​​​​warName​​​​>Spring4MVCApacheTiles3Example</​​​​warName​​​​>​

​<​​​​failOnMissingWebXml​​​​>false</​​​​failOnMissingWebXml​​​​>​

​</​​​​configuration​​​​>​

​</​​​​plugin​​​​>​

​</​​​​plugins​​​​>​

​</​​​​pluginManagement​​​​>​

​<​​​​finalName​​​​>Spring4MVCApacheTiles3Example</​​​​finalName​​​​>​

​</​​​​build​​​​>​

​</​​​​project​​​​>​


Apart from usual Spring dependencies, We have also added few dependencies for Apache Tiles 3. Additional dependencies can be added for more ​​advanced tiles usage​​​. ​​Maven Apache-tiles​​ page lists all the dependencies from basic to advanced usages.

Step 3: Configure Tiles

Configure tiles in Spring Application configuration file.


​package​​​ ​​com.websystique.springmvc.configuration;​

 

​import​​​ ​​org.springframework.context.annotation.Bean;​

​import​​​ ​​org.springframework.context.annotation.ComponentScan;​

​import​​​ ​​org.springframework.context.annotation.Configuration;​

​import​​​ ​​org.springframework.web.servlet.config.annotation.EnableWebMvc;​

​import​​​ ​​org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;​

​import​​​ ​​org.springframework.web.servlet.config.annotation.ViewResolverRegistry;​

​import​​​ ​​org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;​

​import​​​ ​​org.springframework.web.servlet.view.tiles3.TilesConfigurer;​

​import​​​ ​​org.springframework.web.servlet.view.tiles3.TilesViewResolver;​

 

 

​@Configuration​

​@EnableWebMvc​

​@ComponentScan​​​​(basePackages = ​​​​"com.websystique.springmvc"​​​​)​

​public​​​ ​​class​​​ ​​AppConfig ​​​​extends​​​ ​​WebMvcConfigurerAdapter{​

 

​/**​

​* Configure TilesConfigurer.​

​*/​

​@Bean​

​public​​​ ​​TilesConfigurer tilesConfigurer(){​

​TilesConfigurer tilesConfigurer = ​​​​new​​​ ​​TilesConfigurer();​

​tilesConfigurer.setDefinitions(​​​​new​​​ ​​String[] {​​​​"/WEB-INF/views/**/tiles.xml"​​​​});​

​tilesConfigurer.setCheckRefresh(​​​​true​​​​);​

​return​​​ ​​tilesConfigurer;​

​}​

 

​/**​

​* Configure ViewResolvers to deliver preferred views.​

​*/​

​@Override​

​public​​​ ​​void​​​ ​​configureViewResolvers(ViewResolverRegistry registry) {​

​TilesViewResolver viewResolver = ​​​​new​​​ ​​TilesViewResolver();​

​registry.viewResolver(viewResolver);​

​}​

 

​/**​

​* Configure ResourceHandlers to serve static resources like CSS/ Javascript etc...​

​*/​

 

​@Override​

​public​​​ ​​void​​​ ​​addResourceHandlers(ResourceHandlerRegistry registry) {​

​registry.addResourceHandler(​​​​"/static/**"​​​​).addResourceLocations(​​​​"/static/"​​​​);​

​}​

 

​}​


Highlights of above configurations are ​​TilesConfigurer​​​ & ​​TilesViewResolver​​. TilesConfigurer simply configures a TilesContainer using a set of files containing definitions, to be accessed by TilesView instances. Definition files are basically XML files containing layout definitions.

In our Spring MVC application, we also need a ViewResolver. Spring comes with a Tiles specific ViewResolver named TilesViewResolver. Once configured, the view names returned from your controller methods will be treated as tiles view and Spring will look for a definition having the same name in definitions XML files.

Step 4: Create tiles definitions

Shown below is the definition file ​​tiles.xml​


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

​<!​​​​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​​​​>  ​

 

​<!-- Base Definition -->​

​<​​​​definition​​​ ​​name​​​​=​​​​"base-definition"​

​template​​​​=​​​​"/WEB-INF/views/tiles/layouts/defaultLayout.jsp"​​​​>  ​

​<​​​​put-attribute​​​ ​​name​​​​=​​​​"title"​​​ ​​value​​​​=​​​​""​​​ ​​/>  ​

​<​​​​put-attribute​​​ ​​name​​​​=​​​​"header"​​​ ​​value​​​​=​​​​"/WEB-INF/views/tiles/template/defaultHeader.jsp"​​​ ​​/>  ​

​<​​​​put-attribute​​​ ​​name​​​​=​​​​"menu"​​​ ​​value​​​​=​​​​"/WEB-INF/views/tiles/template/defaultMenu.jsp"​​​ ​​/>  ​

​<​​​​put-attribute​​​ ​​name​​​​=​​​​"body"​​​ ​​value​​​​=​​​​""​​​ ​​/>  ​

​<​​​​put-attribute​​​ ​​name​​​​=​​​​"footer"​​​ ​​value​​​​=​​​​"/WEB-INF/views/tiles/template/defaultFooter.jsp"​​​ ​​/>  ​

​</​​​​definition​​​​>  ​

 

​<!-- Home Page -->​

​<​​​​definition​​​ ​​name​​​​=​​​​"home"​​​ ​​extends​​​​=​​​​"base-definition"​​​​>  ​

​<​​​​put-attribute​​​ ​​name​​​​=​​​​"title"​​​ ​​value​​​​=​​​​"Welcome"​​​ ​​/>  ​

​<​​​​put-attribute​​​ ​​name​​​​=​​​​"body"​​​ ​​value​​​​=​​​​"/WEB-INF/views/pages/home.jsp"​​​ ​​/>  ​

​</​​​​definition​​​​>  ​

 

​<!-- Product Page -->​

​<​​​​definition​​​ ​​name​​​​=​​​​"products"​​​ ​​extends​​​​=​​​​"base-definition"​​​​>  ​

​<​​​​put-attribute​​​ ​​name​​​​=​​​​"title"​​​ ​​value​​​​=​​​​"Products"​​​ ​​/>  ​

​<​​​​put-attribute​​​ ​​name​​​​=​​​​"body"​​​ ​​value​​​​=​​​​"/WEB-INF/views/pages/products.jsp"​​​ ​​/>  ​

​</​​​​definition​​​​>  ​

 

​<!-- Contact-us Page -->​

​<​​​​definition​​​ ​​name​​​​=​​​​"contactus"​​​ ​​extends​​​​=​​​​"base-definition"​​​​>  ​

​<​​​​put-attribute​​​ ​​name​​​​=​​​​"title"​​​ ​​value​​​​=​​​​"Contact Us"​​​ ​​/>  ​

​<​​​​put-attribute​​​ ​​name​​​​=​​​​"body"​​​ ​​value​​​​=​​​​"/WEB-INF/views/pages/contactus.jsp"​​​ ​​/>  ​

​</​​​​definition​​​​>  ​

 

​</​​​​tiles-definitions​​​​>​


In above definition file, we have defined a base-definition and several other definitions extending base-definition. Other defintions are just overwriting the part they are specialized for. ​​template​​ attribute in definition-block is used to specify the actual layout file. Each of the definition (by name) can be treated as a tiles-view.

Step 5: Create Layouts

In our case we have defined a basic layout [/WEB-INF/views/tiles/layouts/defaultLayout.jsp] pinned with definition using ​​template​​ attribte.

​defaultLayout.jsp​


​<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>​

​<%@ page isELIgnored="false" %>​

​<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>​

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

 

​<​​​​html​​​​>​

 

​<​​​​head​​​​>​

​<​​​​meta​​​ ​​http-equiv​​​​=​​​​"Content-Type"​​​ ​​content​​​​=​​​​"text/html; charset=ISO-8859-1"​​​​>​

​<​​​​title​​​​><​​​​tiles:getAsString​​​ ​​name​​​​=​​​​"title"​​​ ​​/></​​​​title​​​​>​

​<​​​​link​​​ ​​href="<c:url ​​​​value​​​​=​​​​'/static/css/bootstrap.css'​​​ ​​/>"  rel="stylesheet"></​​​​link​​​​>​

​<​​​​link​​​ ​​href="<c:url ​​​​value​​​​=​​​​'/static/css/app.css'​​​ ​​/>" rel="stylesheet"></​​​​link​​​​>​

​</​​​​head​​​​>​

 

​<​​​​body​​​​>​

​<​​​​header​​​ ​​id​​​​=​​​​"header"​​​​>​

​<​​​​tiles:insertAttribute​​​ ​​name​​​​=​​​​"header"​​​ ​​/>​

​</​​​​header​​​​>​

 

​<​​​​section​​​ ​​id​​​​=​​​​"sidemenu"​​​​>​

​<​​​​tiles:insertAttribute​​​ ​​name​​​​=​​​​"menu"​​​ ​​/>​

​</​​​​section​​​​>​

 

​<​​​​section​​​ ​​id​​​​=​​​​"site-content"​​​​>​

​<​​​​tiles:insertAttribute​​​ ​​name​​​​=​​​​"body"​​​ ​​/>​

​</​​​​section​​​​>​

 

​<​​​​footer​​​ ​​id​​​​=​​​​"footer"​​​​>​

​<​​​​tiles:insertAttribute​​​ ​​name​​​​=​​​​"footer"​​​ ​​/>​

​</​​​​footer​​​​>​

​</​​​​body​​​​>​

​</​​​​html​​​​>​


This layout file provides the consistent look-n-feel across your application. If you want to change layout, define a corresponding layout file and attach to the definition using template attribute.

As you can see, we have a header,footer,menu & body. We are using ​​tags-tiles​​ tag library to provide the placeholder within layout file. Attributes specified using insertAttribute will be provided by corresponding definition(or the one extending it).

Step 6: Create views

We have created some default views[used when the extending definition does not overwrite them] and some specific ones.
​​​defaultHeader.jsp​


​<​​​​div​​​​>​

​<​​​​h1​​​​>Tiles Demo</​​​​h1​​​​>​

​</​​​​div​​​​>​


​defaultFooter.jsp​


​<​​​​div​​​​>​

​Made in this world.​

​</​​​​div​​​​>​


​defaultMenu.jsp​


​<​​​​nav​​​​>​

​<​​​​a​​​ ​​href​​​​=​​​​"${pageContext.request.contextPath}/"​​​​><​​​​img​​​ ​​class​​​​=​​​​"logo"​​​ ​​src​​​​=​​​​"${pageContext.request.contextPath}/static/img/Linux-icon.png"​​​​></​​​​a​​​​>​

​<​​​​ul​​​ ​​id​​​​=​​​​"menu"​​​​>​

​<​​​​li​​​​><​​​​a​​​ ​​href​​​​=​​​​"${pageContext.request.contextPath}/"​​​​>Home</​​​​a​​​​></​​​​li​​​​>​

​<​​​​li​​​​><​​​​a​​​ ​​href​​​​=​​​​"${pageContext.request.contextPath}/products"​​​​>Products</​​​​a​​​​></​​​​li​​​​>​

​<​​​​li​​​​><​​​​a​​​ ​​href​​​​=​​​​"${pageContext.request.contextPath}/contactus"​​​​>Contact Us</​​​​a​​​​></​​​​li​​​​>​

​</​​​​ul​​​​>​

​</​​​​nav​​​​>​


​home.jsp​


​<​​​​h2​​​​>Welcome to Home page</​​​​h2​​​​>​


​products.jsp​


​<​​​​h2​​​​>Products page</​​​​h2​​​​>​


​contactus.jsp​


​<​​​​h2​​​​>Contact Us Page</​​​​h2​​​​>​


Step 7: Create Controller


​package​​​ ​​com.websystique.springmvc.controller;​

 

​import​​​ ​​org.springframework.stereotype.Controller;​

​import​​​ ​​org.springframework.ui.ModelMap;​

​import​​​ ​​org.springframework.web.bind.annotation.RequestMapping;​

​import​​​ ​​org.springframework.web.bind.annotation.RequestMethod;​

 

 

 

​@Controller​

​@RequestMapping​​​​(​​​​"/"​​​​)​

​public​​​ ​​class​​​ ​​AppController {​

 

​@RequestMapping​​​​(value = { ​​​​"/"​​​​}, method = RequestMethod.GET)​

​public​​​ ​​String homePage(ModelMap model) {​

​return​​​ ​​"home"​​​​;​

​}​

 

​@RequestMapping​​​​(value = { ​​​​"/products"​​​​}, method = RequestMethod.GET)​

​public​​​ ​​String productsPage(ModelMap model) {​

​return​​​ ​​"products"​​​​;​

​}​

 

​@RequestMapping​​​​(value = { ​​​​"/contactus"​​​​}, method = RequestMethod.GET)​

​public​​​ ​​String contactUsPage(ModelMap model) {​

​return​​​ ​​"contactus"​​​​;​

​}​

​}​


Look at each of these controller methods. The returned value from them is treated as tiles-view [Thanks to TilesViewResolver] and corresponding tiles-definition gets consulted.

Step 8: Create Initializer


​package​​​ ​​com.websystique.springmvc.configuration;​

 

​import​​​ ​​org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;​

 

​public​​​ ​​class​​​ ​​AppInitializer ​​​​extends​​​ ​​AbstractAnnotationConfigDispatcherServletInitializer {​

 

​@Override​

​protected​​​ ​​Class<?>[] getRootConfigClasses() {​

​return​​​ ​​new​​​ ​​Class[] { AppConfig.​​​​class​​​ ​​};​

​}​

 

​@Override​

​protected​​​ ​​Class<?>[] getServletConfigClasses() {​

​return​​​ ​​null​​​​;​

​}​

 

​@Override​

​protected​​​ ​​String[] getServletMappings() {​

​return​​​ ​​new​​​ ​​String[] { ​​​​"/"​​​ ​​};​

​}​

 

​}​


Step 9: Build, deploy and Run Application

Now build the war (either by eclipse as was mentioned in previous tutorials) or via maven command line( ​​mvn clean install​​​). Deploy the war to a Servlet 3.0 container . Since here i am using Tomcat, i will simply put this war file into ​​tomcat webapps folder​​​ and click on ​​startup.bat​​ inside tomcat/bin directory.

If you prefer to deploy from within Eclipse using tomcat: For those of us, who prefer to deploy and run from within eclipse, and might be facing difficulties setting Eclipse with tomcat, the detailed step-by-step solution can be found at : ​​How to setup tomcat with Eclipse​​.

Open browser and browse at http://localhost:8080/Spring4MVCApacheTiles3Example/

Spring 4 MVC+Apache Tiles 3 Example_spring

Click on different menu items to see the content gets changes while preserving the actual look-n-feel.

Spring 4 MVC+Apache Tiles 3 Example_spring_05

Spring 4 MVC+Apache Tiles 3 Example_apache_06

Download Source Code

 

​Download Now!​


 

References

​http://websystique.com/springmvc/spring-4-mvc-apache-tiles-3-annotation-based-example/​