Struts2 Tiles Integration
Introduction
For any Web application with a sizeable number of application screens it is essential to have a design which promotes page reuse and screen composition flexibility. There are two common patterns used for maximizing reuse when similar application screens are built; Decorator pattern and Composite view pattern. Apache Tiles is a composite view pattern framework for Java web applications. This is a step by step tutorial on integrating Apache Tiles framework in a Struts 2 application. Struts 2 simplifies the adoption of Tiles framework by providing a plugin for integration.
I use the following tools for this tutorial,
- Oracle Java JDK 1.6
- Apache Struts 2.2.3.1
- Apache Tiles 2.0.6
- Struts 2 Tiles Plugin 2.2.3.1
- Eclipse or NetBeans with Maven 3
Apache Tiles Features – Quick Introduction To Tiles
Let us say a Web application requires a number of application pages which requires same header data. The traditional way of avoiding duplication of header content is to use JSP includes in all the pages. This promotes reuse of the same header page in all the screens. In order to change header content, you just need to edit one file. However there is one major disadvantage to this. If you want to change the layout of your application, you will have to change all the pages you have created for your application!
This is where Apache Tiles comes for our rescue. Tiles can extract the layout information and then individual pages can decide what layout they want to use. This way layout change will be limited to changes in a single layout file. See the following Struts 2 Tiles sample application to learn how Tiles can compose a screen from individual pages and a layout file. Check out Tiles tutorial to learn more about Apache Tiles.
Apache Tiles can be used in complex page composition use cases by using some of its key features,
- Page definitions can be nested or can inherit from other page definitions
- It is possible to create tiles page definitions at compile time or at runtime
- View prepares enables preparation of data before rendering page definitions
Creating a Struts 2 Tiles Application
Create a simple Struts 2 application using Maven archetypes. Follow the Struts 2 Maven Eclipse tutorial or Struts 2 Maven NetBeans tutorial to setup a Struts 2 project using Maven. Delete all the files generated except web.xml, struts.xml and pom.xml from the project. Add the Struts 2 Tiles plugin as a project dependency by appending the following entry to the dependencies section of pom.xml in your project.
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-tiles-plugin</artifactId>
<version>2.2.3.1</version>
<scope>compile</scope>
</dependency>
Note that Struts 2 Tiles Plugin 2.2.3.1 project has a dependency with Tiles 2.0.6 (automatically downloaded by Maven). If you want to use latest Tiles jars (2.2.2), you can manually add the dependency in pom.xml and exclude the 2.0.6 dependencies from Struts 2 Tiles Plugin. Alternatively you can manually setup the project instead of using Maven.
Add the Struts2TilesListener as an event listener by adding the following lines to web.xml.
<listener>
<listener-class>org.apache.struts2.tiles.StrutsTilesListener</listener-class>
</listener>
Our application requirement is to create 3 application screens all of which will have the same layout. The only thing that will vary between the screens is the body area. Tiles is an ideal choice to develop a common template for these screens.

First create a file named tiles.xml under WEB-INF folder (the folder where web.xml is located). By default this is where Tiles will look for its configuration file. We will add an abstract screen definition and then extend the definition to create 3 page definitions corresponding to the above screens. In each screen definition we will override the body section by passing the name of the JSP file which contains the content of that screen.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
"http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
<tiles-definitions>
<definition name="struts2tiles.mainLayout" template="/templates/mainlayout.jsp">
<put-attribute name="header" value="/common/header.jsp"/>
<put-attribute name="body" value=""/>
<put-attribute name="footer" value="/common/footer.jsp"/>
</definition>
<definition name="struts2tiles.home" extends="struts2tiles.mainLayout">
<put-attribute name="body" value="/pages/home.jsp"/>
</definition>
<definition name="struts2tiles.page1" extends="struts2tiles.mainLayout">
<put-attribute name="body" value="/pages/page1.jsp"/>
</definition>
<definition name="struts2tiles.page2" extends="struts2tiles.mainLayout">
<put-attribute name="body" value="/pages/page2.jsp"/>
</definition>
</tiles-definitions>
First let us create the template file (mainlayout.jsp). This uses Tiles tags to compose the screen from various attributes passed to the template via page definitions.
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
<!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=UTF-8">
<title><tiles:insertAttribute name="title" ignore="true" /></title>
</head>
<body>
<table border="1" cellpadding="2" cellspacing="2" align="center">
<tr style="background-color: #66f;">
<td>
<tiles:insertAttribute name="header" />
</td>
</tr>
<tr style="background-color: #aaa;">
<td width="350">
<tiles:insertAttribute name="body" />
</td>
</tr>
<tr style="background-color: #f66;">
<td >
<tiles:insertAttribute name="footer" />
</td>
</tr>
</table>
</body>
</html>
Let us now create the common jsps (header.jsp and footer.jsp).
<h1>Header</h1>
<h1>Footer</h1>
Let us create the individual page content (home.jsp, page1.jsp and page2.jsp). These contain dummy data to test our implementation.
<h1>Home</h1>
<h1>Page 1</h1>
<h1>Page 2</h1>
Update the struts.xml with the following content.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="false"/>
<constant name="struts.devMode" value="true"/>
<package name="default" extends="struts-default">
<result-types>
<result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult"/>
</result-types>
<action name="Home" class="org.struts2.struts2tiles.Home">
<result name="success" type="tiles">struts2tiles.home</result>
</action>
<action name="Page1" class="org.struts2.struts2tiles.Page1">
<result name="success" type="tiles">struts2tiles.page1</result>
</action>
<action name="Page2" class="org.struts2.struts2tiles.Page2">
<result name="success" type="tiles">struts2tiles.page2</result>
</action>
</package>
</struts>
Note that the result type "tiles" is defined as a the TilesResult class. So whenever Struts encounters a result of the type "tiles" it will invoke TilesResult. TilesResult will use the content of the result tag to find the corresponding page definition in tiles.xml! So in this example, Home action has a "success result" of type" tiles" and hence TilesResult will look for struts2tiles.home definition in tiles.xml.
Create all the action classes specified in struts.xml (Home, Page1 and Page2). These action classes are used to forward the request to various view pages (Tiles page definitions in this case).
package org.struts2.struts2tiles;
import com.opensymphony.xwork2.ActionSupport;
public class Home extends ActionSupport{
@Override
public String execute() {
return SUCCESS;
}
}
package org.struts2.struts2tiles;
import com.opensymphony.xwork2.ActionSupport;
public class Page1 extends ActionSupport {
@Override
public String execute() {
return SUCCESS;
}
}
package org.struts2.struts2tiles;
import com.opensymphony.xwork2.ActionSupport;
public class Page2 extends ActionSupport{
@Override
public String execute() {
return SUCCESS;
}
}
Run the project and access the various screens by invoking the following links if you are using NetBeans (Use port 8080 for Eclipse).
http://localhost:8084/Struts2Tiles-1.0-SNAPSHOT/Home.action
http://localhost:8084/Struts2Tiles-1.0-SNAPSHOT/Page1.action
http://localhost:8084/Struts2Tiles-1.0-SNAPSHOT/Page2.action
If you manually setup the Struts 2 Tiles application in your IDE(if you don’t like Maven for some reason!), ensure that you add the following jars in the lib folder,
asm-3.1.jar asm-commons-3.1.jar asm-tree-3.1.jar commons-beanutils-1.7.0.jar commons-digester-1.8.jar commons-fileupload-1.2.2.jar commons-io-2.0.1.jar commons-lang-2.5.jar commons-logging-1.1.1.jar commons-logging-api-1.1.jar freemarker-2.3.16.jar javassist-3.11.0.GA.jar ognl-3.0.1.jar struts2-config-browser-plugin-2.2.3.1.jar struts2-core-2.2.3.1.jar struts2-tiles-plugin-2.2.3.1.jar tiles-api-2.0.6.jar tiles-core-2.0.6.jar tiles-jsp-2.0.6.jar xwork-core-2.2.3.1.jar
Download Struts 2 Tiles Example
- Click here to download Struts 2 Tiles example source code (Struts 2 Maven Project) – Use this tutorial to setup the source code in NetBeans.
November 28, 2011 | Posted in Tutorials No Comments »
