Integración de Spring MVC 3 y Tiles 2

Versión para imprimirVersión PDF

Spring MVC es un framework ligero para desarrollo de aplicaciones web que implementa el patrón Modelo-Vista-Controlador. Con Spring MVC podemos generar controladores basados en POJO's a través de anotaciones como @Controller y @RequestMapping, podemos realizar mapeo de peticiones, resolución de vistas, gestión de internacionalización e incluso resolución de temas.

Por otro lado Tiles es también un framework para desarrollo de aplicaciones web, aunque orientado a la presentación de nuestras páginas a través de plantillas. Lo cual nos permite reutilizar código y tener páginas mejor organizadas y sencillas.

En este artículos vamos a crear una aplicación web desde cero en la cual demostraremos el proceso de integración de Spring MVC 3 con Tiles 2.

Crear aplicación web con maven

El primero paso es crear la aplicación web con Maven para lo cual haremos uso del siguiente comando.

mvn archetype:create -DgroupId=org.yaxche.blog -DartifactId=org.yaxche.blog.springtiles -DarchetypeArtifactId=maven-archetype-webapp

Agregar dependencias

Al POM generado para el proyecto debemos agregar las dependencias de los proyectos Spring MVC y Tiles y alguna más que veremos a continuación.

Dependencia de Spring MVC

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-webmvc</artifactId>
	<version>3.0.5.RELEASE</version>
	<type>jar</type>
	<scope>compile</scope>
</dependency>

Dependencia de Spring MVC

<dependency>
	<groupId>org.apache.tiles</groupId>
	<artifactId>tiles-jsp</artifactId>
	<version>2.2.2</version>
	<type>jar</type>
	<scope>compile</scope>
</dependency>

Dependencia de SLF4J

Esta dependencia se debe agregar en caso de que no estemos utilizando algún otro framework logging ya que SLF4J al no detectar (por ejemplo a log4j o commons-logging) utilizará al API de Java para realizar el trazado (para lo cual requiere la siguiente dependencia). En caso de querer utilizar otro framework de logging debemos sustituir la dependencias por la que corresponda.

<dependency>
	<groupId>org.slf4j</groupId>
	<artifactId>slf4j-jdk14</artifactId>
	<version>1.5.8</version>
	<type>jar</type>
	<scope>compile</scope>
</dependency>

Configuración de Spring MVC

Para configurar Spring MVC en nuestra aplicación web debemos editar el archivo web.xml de la siguiente manera.

Primero agregaremos como la especificación del Servlet de Spring que atenderá las peticiones.

<!-- Servlet para atender las peticiones de SpringFramework. -->
<servlet>
  <servlet-name>dispatcher</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>

Después agregamos la configuración del mapeo de las peticiones que serán atendidas por el Servlet de Spring.

<servlet-mapping>
  <servlet-name>dispatcher</servlet-name>
  <url-pattern>*.yaxche</url-pattern>
</servlet-mapping>

El servlet de spring requiere de un archivo de configuración (del contexto del contenedor IoC). En este caso debe llamarse dispatcher-servlet.xml y debe estar ubicado dentro del directorio WEB-INF. Aprovecharemos para agregar dentro de este archivo la siguiente configuración que nos será útil más adelante.

  <context:annotation-config></context:annotation-config>
  <context:component-scan base-package="org.yaxche.blog"></context:component-scan>

Como se puede intuir las líneas anteriores sirven para escanear en busca de beans configurados en base a anotaciones a partir de la jerarquía de paquetes especificada.

En el mismo archivo dispatcher-servlet.xml vamos a configurar el componente que resolverá la ubicación de las vistas.

<bean id="viewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
  <property name="basename" value="views"></property>
</bean>

En este caso hemos seleccionado el gestor de vistas basado en un archivo de propiedades el cual hemo indicado a través de la propiedad basename que se llamará views.properties y estará ubicado a nivel raíz dentro del classpath de la aplicación.

En este punto ya tenemos la casi toda configuración necesaria para echar a andar una aplicación web con spring mvc, sólo restaría programar los Controladores y entonces configurar sus vistas dentro del archivo views.properties.

Integración de Tiles

El siguiente paso es integrar a Tiles dentro de nuestra aplicación, para lo cual debemos configurar el bean TilesConfigurer proporcionado por Spring, dentro de dispatcher-servlet.xml.

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

La propiedad definitions recibe un listado de archivos con las definiciones que Tiles requiere para presentar las páginas. En nuestro ejemplo estamos especificando sólo un archivo e indicamos que se encuentra en el siguiente path: /WEB-INF/config/tiles-defs.xml.

En el siguiente fragmento del archvo tiles-defs.xml, se prenseta la definición base que utilizaremos para el ejemplo.

<?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="yaxcheSpringTilesBase" template="/WEB-INF/view/yaxche/springtiles/common/layout.jsp">
    <put-attribute name="title" value="Yaxché Blog. Integración Spring MVC 3 - Tiles 2"/>
    <put-attribute name="header" value="/WEB-INF/view/yaxche/springtiles/common/header.html"/>
    <put-attribute name="menu" value="/WEB-INF/view/yaxche/springtiles/common/menu.jsp"/>
    <put-attribute name="body" value=""/>
    <put-attribute name="footer" value="/WEB-INF/view/yaxche/springtiles/common/footer.html"/>
  </definition>
</tiles-definitions>

En nuestra definición base hemos declarado la plantilla a utilizar a través de la propiedad template así como los elementos estructurales de la plantilla como título, cabecera, menú, cuerpo y pie a través del tag put-attribute.

Por otro lado el atributo body lo estamos dejando sin valor, esto es porque en tiles podemos extender las definiciones sobre escibiendo propiedades y definiendo las que estaban vacías en la definición base.

Plantilla

A continuación se muestra el código de la plantilla (layout.jsp)

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><tiles:insertAttribute name="title"/></title>
</head>
<body id="bodyPage" bgcolor="#FFFFFF" text="#000000" leftmargin="0" topmargin="0"
  marginwidth="0" marginheight="0" link="#FFFFFF" vlink="#FFFFFF" alink="#FFFFFF">
<div id="block-header" style="width: 100%; background-color: #5CB323; border-style: solid; border-width: 1px; border-color: #5CBF23; color: #FFFFFF;" align="center">
  <tiles:insertAttribute name="header"/>
</div>
<div id="block-menu" style="width: 24%; background-color: #FF690B; border-style: solid; border-width: 1px; border-color: #FF695B; padding: 1px; float: left;" align="left">
  <tiles:insertAttribute name="menu"/>
</div>
<div id="block-body" style="width: 74%; background-color: #FFFFFF; border-style: solid; padding: 2px; float: left; color: #000000;" align="justify">
  <tiles:insertAttribute name="body"/>
</div>
<div id="block-footer" style="width: 100%; background-color: #5CB323; border-style: solid; border-width: 1px; border-color: #5CBF23; color: #FFFFFF;" align="center">
  <tiles:insertAttribute name="footer"/>
</div>
</body>
</html>

Cabe destacar la correspondencia de los elementos definidos en el tiles-defs.xml a través de los tags tiles:insertAttribute.

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

Cabecera

<h1>Yaxché Blog. Integración Spring MVC 3 - Tiles 2</h1>

Pie

<p><h4>
  <a href="http://www.yaxche-soft.com">Yaxché</a>. <i>Desarrollando una nueva identidad para el software empresarial.</i>
</h4></p>

Menú

<p><a href="welcome.yaxche">Bienvenido</a></p>
<p><a href="about.yaxche">Acerca de...</a></p>

Vemos que nuestra aplicación tendrá 2 páginas que serán atendidas por el DispatcherServlet de spring ya que cumplen con el mapeo definido *.yaxche.

Crear el controlador para welcome.yaxche

Los controladores de nuestra aplicación serán muy sencillos cada uno gestionará una URL devolviendo la vista por presentar sin desarrollar ningún tipo de lógica.

@Controller("welcomeCtlr")
public class WelcomeController {

	@RequestMapping("welcome.yaxche")
	public ModelAndView show() {
		return new ModelAndView("welcomeView");
	}
}

Dado que anteriormente hemos hecho uso de las anotaciones context:annotation-config y context:component-scan dentro de dispatcher-servlet.xml nuestro controlador será cargado dentro del contexto del contenedor IoC, debido a que lo estámos "marcando" con la anotación @Controller. Además vemos que el método show está "marcado" con la anotación @RequestMapping esto indica que las peticiones hechas a "welcome.yaxche" serán atendidas por este método. Finalmente el método show devuelve un ModelAndView especificando el nombre de vista "welcomeView" lo cual se deberá configurar en el archivo de vistas.

Para más detalles acerca de SPring MVC puedes ver Controladores basados en anotaciones y Mapeo de peticiones.

Configuración de la vista welcomeView

Ahora que ya tenemos nuestro controlador y que sabemos lo que devuelve, debemos indicarle al gestor de vista cómo resolver la vista. Si recordamos en el dispatcher-servlet.xml hemos configurado anteriormente el bean viewResolver en donde especificamos que la resolución de las vistas sería a través del archivo de configuración views.properties ubicado a nivel raíz del classpath de la aplicación. Toca entonces editar en dicho archivo la configuración para la vista "welcomeView".

welcomeView.(class)=org.springframework.web.servlet.view.tiles2.TilesView
welcomeView.url=welcome

Como se ve hemos agregado un par de líneas en dónde especificamos la clase que resolvera la vista (org.springframework.web.servlet.view.tiles2.TilesView) y la URL en dónde se ubica la vista. Al traterse de una vista resuelta por la clase TilesView el valor por configurar en el url (welcomeView.url) no es el nombre de un JSP sino el nombre de una definición ubicada en cualquiera de los archivos especificados en la propiedad definitions del bean tilesConfigurer. Es decir que en nuestro ejemplo debemos tener una definición llamada "welcome" dentro del archivo /WEB-INF/config/tiles-defs.xml.

Definición Tiles para welcome

En el archivo de definiciones de tiles ya teniamos una definción base en la cual sólo faltaba agragar un valor para el atributo body. Ahora agregaremos una nueva definición para la vista "welcomView".

  <definition name="welcome" extends="yaxcheSpringTilesBase">
    <put-attribute name="body" value="/WEB-INF/view/yaxche/springtiles/content/welcome.jsp"/>
  </definition>

La nueva definición extiende de la base que ya se tenía y agrega el atributo body especificando la ubicación del JSP a presentar. El JSP sólo muestra un mensaje de bienvenida.

welcome.jsp

<h2>Bienvenidos.</h2>
<p>Esta es la página inicial del ejemplo de integración de Spring MVC 3 y Tiles 2</p>

Ya tenemos todo lo necesario para desplegar la primera página, en este punto se puede compilar la aplicación y realizar la primera prueba.

Crear el controlador para about.yaxche

@Controller("aboutCtlr")
public class AboutController {

	@RequestMapping("about.yaxche")
	public ModelAndView show() {
		return new ModelAndView("aboutView");
	}
}

Configuración de la vista aboutView

aboutView.(class)=org.springframework.web.servlet.view.tiles2.TilesView
aboutView.url=about

Definición Tiles para welcome

  <definition name="about" extends="yaxcheSpringTilesBase">
    <put-attribute name="body" value="/WEB-INF/view/yaxche/springtiles/content/about.jsp"/>
  </definition>

about.jsp

<h2>El blog Yaxché</h2>
<p>Un punto de encuentro en donde compartir conocimientos.</p>

Hemos terminado nuestra aplicación es tiempo de empaquetar y desplegar. Para ellos podemos hacer uso de los siguientes comandos maven.

mvn dependency:resolve

A manera de buena práctica cuando creo un nuevo proyecto con maven y cuando agrego dependencias ejecuto este comando para saber si hace falta alguna dependencia aún antes de compilar el código.

mvn package

Puedes descargar el código de la aplicación ejemplo aquí, fue probado desplegandolo en Glassfish v 2.1.

Como se ha visto integrar Spring MVC y Tiles es sencillo aunque lleva varios pasos sobre todo de configuración al final la ventaja de tener nuestras vistas organizadas con plantillas hace que valga la pena realizar los pasos de configuración xml.

Your rating: None Average: 4.5 (6 votes)