Integración Apache Tiles con Spring MVC

Apache Tiles es un framework que nos permitirá organizar de mejor manera la presentación de nuestro sitio web creado con Spring MVC, Tiles funciona como un sistema de plantillas en donde podemos crear pequeños fragmentos de código que pueden ser insertados en cualquier parte de nuestro sitio, organizaremos cada fragmento de modo que represente una parte de nuestra web, cabecera, barras laterales, pie de página, contenido principal, etc., de esta manera evitar la duplicación de código y se hace más fácil realizar cambios en cualquiera de las partes, no tendremos que realizar el cambio página por página.

Integrar Apache Tiles a Spring MVC

Integrar Apache Tiles a una aplicacione web Spring MVC es muy sencillo, adicional a las dependencias que normalmente utilizaramos requerimos la siguiente:

<dependency>
    <groupId>org.apache.tiles</groupId>
    <artifactId>tiles-jsp</artifactId>
    <version>3.0.7</version>
</dependency>

La configuración del Servlet la realizaremos con código Java:

public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() { return null; }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[] { WebAppConfig.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }
}

Integrar Tiles a Spring MVC

Para integrar Apache Tiles a Spring Web debemos agregar un TilesConfigurer y un TilesViewResolver, el primero nos servirá para establecer la configurarción del framework y el segundo es el encargado de resolver la vista, es decir, tomará el nombre enviado por el controlador y elegirá el archivo JSP adecuado.

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"carmelo.spring.controller"})
public class WebAppConfig {

    @Bean
    public TilesConfigurer tilesConfigurer() {
        TilesConfigurer tilesConfigurer = new TilesConfigurer();
        tilesConfigurer.setDefinitions(new String[]{"/WEB-INF/tiles/tiles.xml"});
        tilesConfigurer.setCheckRefresh(true);
        return tilesConfigurer;
    }

    @Bean
    public ViewResolver tilesViewResolver() {
        return new TilesViewResolver();
    }
}

Usando el método setDefinitions() indicamos los archivos de configuración XML para Tiles, puede ser uno o más de ellos.

/WEB-INF/tiles/tiles.xml
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!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>
    
    <definition name="base-template" template="/WEB-INF/template/template.jsp">
        <put-attribute name="title"   value="Spring MVC Tiles Integration" />
        <put-attribute name="content" value="" />
        <put-attribute name="header"  value="/WEB-INF/template/header.jsp" />
        <put-attribute name="footer"  value="/WEB-INF/template/footer.jsp" />
    </definition>
    
    <definition name="product" extends="base-template">
        <put-attribute name="content" value="/WEB-INF/views/product.jsp" />
    </definition>
    
    <definition name="customer" extends="base-template">
        <put-attribute name="content" value="/WEB-INF/views/customer.jsp" />
    </definition>
    
</tiles-definitions>

La etiqueta <definition> nos permite definir una plantilla, le damos un nombre y definimos el archivo JSP que será usado para crear dicha plantilla, la etiqueta <put-attribute> la utilizaremos para definir los “tiles” o fragmentos que componen nuestra plantilla.

/WEB-INF/template/template.jsp
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title><tiles:getAsString name="title" /></title>
    </head>
    <body>
        <div class="header-tile">
            <tiles:insertAttribute name="header" />
        </div>

        <div class="content-tile">
            <tiles:insertAttribute name="content" />
        </div>

        <div class="footer-tile">
            <tiles:insertAttribute name="footer" />
        </div>    
    </body>
</html>

Agregamos el taglib correspondiente para poder acceder a los tiles, usando tiles:getAsString obtenemos un texto, para nuestro caso el título, con tiles:insertAttribute agregamos el fragmento deseado a nuestra plantilla, como podemos ver hemos añadido un encabezado, el contenido y un pie de página, esta plantilla será usada como base para las demás.

Apache Tiles en Spring Web MVC

Esta es la plantilla que hemos creado, el encabezado y el pie de página estas definido por los archivos header.jsp y footer.jsp respectivamente, el área central no tiene contenido de momento pues este será generado dinámicamente.

El código de abajo muestra la definición para las dos vistas que utilizaremos como ejemplo, podemos ver que extendemos la plantilla base usando el atributo extends, además redefinimos el contenido de la misma, indicando los correspondientes archivos JSP para cada una de ellas.

<definition name="product" extends="base-template">
    <put-attribute name="content" value="/WEB-INF/views/product.jsp" />
</definition>

<definition name="customer" extends="base-template">
    <put-attribute name="content" value="/WEB-INF/views/customer.jsp" />
</definition>

Los archivos product.jsp y customer.jsp ya los hemos visto en tutoriales previos, si deseas más información de cómo generar vistas JSP puedes dirigirte al tutorial: Spring MVC Vistas JSP.

/WEB-INF/views/product.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<div>
    <h3 style="font-family: serif;">Product List</h3>
    <table border="1" >
        <tr>
            <th style="width:  50px;">No</th>
            <th style="width: 250px;">Nombre</th>
            <th style="width: 250px;">Precio</th>
        </tr>
        <c:forEach var="product" 
                   items="${products}"
                   varStatus="status">
            <tr>
                <td>${status.index + 1}</td>
                <td>${product.name}</td>
                <td>${product.price}</td>
            </tr>
        </c:forEach>
    </table>
</div>
/WEB-INF/views/customer.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<div>
    <h3 style="font-family: serif;">Customer List</h3>
    <table border="1" >
        <tr>
            <th style="width:  50px;">No</th>
            <th style="width: 250px;">Nombre</th>
            <th style="width: 250px;">Precio</th>
            <th style="width: 250px;">Ciudad</th>
        </tr>
        <c:forEach var="customer" 
                   items="${customers}"
                   varStatus="status">
            <tr>
                <td>${status.index + 1}</td>
                <td>${customer.firstName}</td>
                <td>${customer.lastName}</td>
                <td>${customer.city}</td>
            </tr>
        </c:forEach>
    </table>
</div>

El TilesViewResolver que definimos previamente tomará el nombre devuelto por el controlador y buscará en el archivo tiles.xml la definición correspondiente.

@Controller
public class HomeController {

    @RequestMapping(value = {"/products"})
    public String productList(Model model) {
        model.addAttribute("products", Product.getProductList());
        return "product";
    }

    @RequestMapping("/customers")
    public String customerList(Model model) {
        model.addAttribute("customers", Customer.getCustomerList());
        return "customer";
    }
}

Para profundizar en los detalles del controlador dispones del tutorial: Spring MVC Controladores.

Integración Apache Tiles Spring MVC

Con esto hemos logrado agilizar la creación de las vistas, reducir y reutilizar código, si en algún momento deseamos cambiar la cabecera de todo el sitio web solo debemos editar el archivo header.jsp, la modificación se hace más fácil.

Descargar código: Apache Tiles Spring.zip

Comentarios

Entradas populares de este blog

Conectar SQL Server con Java

Gauss Seidel y Jacobi

Entrenar OpenCV en Detección de Objetos

Procesamiento de imágenes en OpenCV

Acceso a la webcam con OpenCV