Tiles 2.2.2 Integration

Last modified by Ken McWilliams on 2012/03/20 22:59

There are some great new features in Apache Tiles 2.2.2 one of these must-have features is wild card support. For a list of features visit the Apache Tiles Features List.

This tutorial requires we have setup a Basic Struts2 Project, and if you have never used tiles before it might be best to start with the Basic Tiles Tutorial.

Gather the Required Dependencies

1) Add struts2-tiles-plugin-2.3.1.2.jar or greater added to your Struts2 2.3.1.2 project.

2a) [optional] Some of the features of tiles are only available by adding spring dependencies (you will be able complete this tutorial and get wild card support without these jars).  If you wish to have these required dependancies it is recommended that you follow the spring tutorial.

2b) If 2a was not done then we must add slf4j-api-1.6.1.jar (it is a spring dependency so would not need to be explicitly added if the spring tutorial was followed)

3) Add the following tiles jars (For maven they all have a group of org.apache.tiles, and the artifact id follows the jar):

  • tiles-api-2.2.2.jar Artifiact id: tiles-api
  • tiles-core-2.2.2.jar Artifiact id: tiles-core
  • tiles-jsp.2.2.2.jar Artifiact id: tiles-jsp
  • tiles-servlet-2.2.2.jar Artifiact id: tiles-servlet

Configure 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">
    <listener>
        <listener-class>org.apache.tiles.web.startup.TilesListener</listener-class>
    </listener>
    <context-param>
        <param-name>tilesDefinitions</param-name>
        <param-value>/WEB-INF/tiles.xml</param-value>
    </context-param>
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

NOTE: Either org.apache.struts2.tiles.StrutsTilesListener or org.apache.tiles.web.startup.TilesListener may be used in this example.  I am not certain which is better.  Struts2 states that the StrutsTilesListener offers better integration of Tiles with Struts2 however since we are upgrading to a Tiles version greater than that provided by Struts2 I thought is best to use the one recommended by Tiles.

Configure struts.xml

<?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.devMode" value="true" />
    <constant name="struts.ui.theme" value="simple" />
    <constant name="struts.enable.SlashesInActionNames" value="true" />
    <constant name="struts.mapper.alwaysSelectFullNamespace" value="false"/>
    <package  name="basicstruts2"  namespace="" extends="tiles-default">
        <result-types>
            <result-type name="tiles" default="true" class="org.apache.struts2.views.tiles.TilesResult"/>
        </result-types>

        <action name="/**" >
            <result>{1}</result>
        </action>
    </package>
</struts>

NOTE: The double asterix in the action name.  This selects slashes in the name while a single asterix does not. For more information on this and other struts2 pattern matching see here.

Configure tiles.xml

Add the following to /WEB-INF/tiles.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tiles-definitions PUBLIC
       "-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN"
       "http://tiles.apache.org/dtds/tiles-config_2_1.dtd">
<tiles-definitions>
    <definition name="baseLayout" template="/WEB-INF/tiles/template.jsp">
        <put-attribute name="title" value="Default Title"/>
        <put-attribute name="header" value="/WEB-INF/tiles/header.jsp"/>
        <put-attribute name="body" value="/WEB-INF/tiles/body.jsp"/>
        <put-attribute name="footer" value="/WEB-INF/tiles/footer.jsp"/>
    </definition>
    <definition name="test" extends="baseLayout">
        <put-attribute name="Test Title" value="Default Title"/>
    </definition>
    <definition name="package/*" extends="baseLayout">
        <put-attribute name="title" value="{1}" type="string"/>
    </definition>
    <definition name="" extends="baseLayout">
    </definition>
</tiles-definitions>

Note: With no welcome file specified in the web.xml the empty "" action will be invoked which due to the Struts2 wild cards will in turn call the empty tiles definition.

Add the required JSPs to satisfy the requirements of tiles.xml

/WEB-INF/tiles/template.jsp

<%@taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %>
<%@taglib prefix="s" uri="/struts-tags"%>
<%@page contentType="text/html" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title><tiles:insertAttribute name="title"/></title>
    </head>
    <body>
<tiles:insertAttribute name="header"/>
<tiles:insertAttribute name="body"/>
<tiles:insertAttribute name="footer"/>
    </body>
</html>

/WEB-INF/tiles/body.jsp

<div>
    This is the default body.
</div>

/WEB-INF/tiles/footer.jsp

<div>
    This is the default footer.
</div>

/WEB-INF/tiles/header.jsp

<div>
    This is the default header.
</div>

Test

We can see the only thing that will change between invocations in this test is the page title. The body of the document will remain constant.

Thanks to the initial empty action, which calls the empty tiles definition we have an initial page rendered by tiles.

If we enter an action of test, we will see the page tile becomes "Test Title".

If we enter a value of "/package/xxx" where xxx can be anything we find the page tile becomes xxx, showing our wild cards in action.