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.
- AngularJS+Spring Security using Basic Authentication
- Secure Spring REST API using OAuth2
- Secure Spring REST API using Basic Authentication
- Spring 4 MVC+JPA2+Hibernate Many-to-many Example
- Spring 4 Caching Annotations Tutorial
- Spring 4 Cache Tutorial with EhCache
- Spring 4 Email Template Library Example
- Spring 4 Email With Attachment Tutorial
- Spring 4 Email Integration Tutorial
- Spring MVC 4+JMS+ActiveMQ Integration Example
- Spring 4+JMS+ActiveMQ @JmsLister @EnableJms Example
- Spring 4+JMS+ActiveMQ Integration Example
- Spring MVC 4+Spring Security 4 + Hibernate Integration Example
- Spring MVC 4+AngularJS Example
- Spring MVC 4+AngularJS Server communication example : CRUD application using ngResource $resource service
- Spring MVC 4+AngularJS Routing with UI-Router Example
- Spring MVC 4+Hibernate 4 Many-to-many JSP Example
- Spring MVC 4+Hibernate 4+MySQL+Maven integration + Testing example using annotations
- Spring Security 4 Hibernate Integration Annotation+XML Example
- Spring MVC4 FileUpload-Download Hibernate+MySQL Example
- Spring MVC 4 Form Validation and Resource Handling
- Spring Batch- MultiResourceItemReader & HibernateItemWriter example
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:
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/
Click on different menu items to see the content gets changes while preserving the actual look-n-feel.
Download Source Code
References
http://websystique.com/springmvc/spring-4-mvc-apache-tiles-3-annotation-based-example/