Spring Mvc + Apache Tiles

Apache Tiles is a templating framework for java based web application. 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.

Here we will be building a simple spring mvc 4 xml based web application and integrate with apache tiles 3. We will be using bootstrap for a better look and feel. Our final application will look like:

spring-tiles-final-view

Final project structure:

spring-tiles-project-structure-1spring-tiles-project-structure-2

Update pom.xml to include required dependencies


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mynotes</groupId>
<artifactId>spring-tiles</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>

<properties>
<springframework-version>4.3.2.RELEASE</springframework-version>
<tiles-version>3.0.5</tiles-version>
</properties>
<dependencies>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>

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

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

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

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

</dependencies>
<build>
<finalName>spring-tiles</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<!-- <configuration> <path>/</path> <port>8899</port> </configuration> -->
</plugin>
</plugins>
</build>
</project>

Lets start with web.xml. Here we are specifying the servlet class DispatcherServlet that acts as the front controller in Spring Web MVC. All the incoming request will be forwarded to the DispatcherServlet.


<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<display-name>spring-tiles</display-name>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>

dispatcher-servlet.xml 


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

<mvc:annotation-driven />

<context:component-scan base-package="com.mynotes.spring.tiles.controller" />
<mvc:resources mapping="/static/**" location="/static/"/>

<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.tiles3.TilesView" />
</bean>

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

</beans>

Notice the 2 bean here. viewResolver view class is TilesView and the tilesConfigurer definition is in 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 Define -->
<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/header.jsp" />
<put-attribute name="menu" value="/WEB-INF/views/tiles/template/menu.jsp" />
<put-attribute name="body" value="" />
<put-attribute name="footer" value="/WEB-INF/views/tiles/template/footer.jsp" />
</definition>

<!-- Home Page -->
<definition name="home" extends="base.definition">
<put-attribute name="title" value="Home Page" />
<put-attribute name="body" value="/WEB-INF/views/pages/home.jsp" />
</definition>

<!-- Products 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. Base definition is were you map your header,footer files.  template attribute in definition-block is used to specify the actual layout file. defaultLayout.jsp is the template. We will be using header,body,footer layout. Body attribute is going to be dynamic and will be replaced each time. Header/footer are going to be fixed. For styling we will be using bootstrap.


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

<head>
<title>Spring Tiles</title>
<meta name="viewport" content="width=device-with, initial-scale=1.0"/>
<link href="/spring-tiles/static/css/bootstrap.min.css" rel="stylesheet">
<link href="/spring-tiles/static/css/styles.css" rel="stylesheet">
</head>

<body>
<tiles:insertAttribute name="header"/>
<tiles:insertAttribute name="body"/>
<tiles:insertAttribute name="footer"/>

<script src="/spring-tiles/static/js/jquery-1.11.0.min.js"></script>
<script src="/spring-tiles/static/js/bootstrap.min.js"></script>
</body>

</html>

header.jsp


<div class="navbar navbar-inverse navbar-static-top">
<div class="container">
<a href="/spring-tiles" class="navbar-brand">Spring Tiles Demo</a>

<button class="navbar-toggle" data-toggle="collapse" data-target=".navHeaderCollapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>

<div class="collapse navbar-collapse navHeaderCollapse">
<ul class="nav navbar-nav navbar-right">
<li><a href="/spring-tiles/home">Home</a></li>
<li><a href="/spring-tiles/products">Products</a></li>
<li><a href="/spring-tiles/contactus" data-toggle="modal">Contact Us</a></li>
</ul>
</div>
</div>
</div>

footer.jsp


<div class="navbar navbar-default navbar-fixed-bottom">
<div class="container text-center">
<p class="navbar-text">Footer Text</p>
</div>
</div>

Let create 3 jsp which will serve as body.

contactus.jsp


<h2 class="text-center">Contact Us Page</h2>

[/code"]

<strong>home.jsp</strong>



<h2 class="text-center">Welcome to Home page</h2>

products.jsp


<h2 class="text-center">Products page</h2>

Finally lets create a simple controller AppController.java to handle different requests. Look at each of these controller methods. The return value of every controller will be mapped with each tiles definition (in tiles.xml) which is associated with jsp to render as body in template.


package com.mynotes.spring.tiles.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 = { "/","/home"}, 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 contactUs(ModelMap model) {
return "contactus";
}
}

All done. Run by mvn tomcat7:run and open http://localhost:8080/spring-tiles/ to check. Click on different links and check.

%d bloggers like this: