Está en la página 1de 10

Struts.

Tiles

Tiles en Struts
Este articulo es una traducción del original de Prakash Malani publicado en javaworld.com. La
traducción esta realizada por Pedro del Gallego Vida.

Introducción

Normalmente el desarrollo de una aplicación Web, el grupo responsable de la interfaz de usuario


(UI) crea el Look and Feel (L&F) del sitio. Basandose en el Look and Feel, este grupo crea paginas
HTML que representan la funcionalidad de la aplicación y la forma de navegar. Con una
implementacion basada en Servlet y JavaServer Pages(JSP), donde las paginas HTML son
convertidas en servlet y JSP, los diseñadores de UI, indentificaron componentes HTML y JSP
comunes, como la cabecera (Header),el cuerpo (Body), el pie de pagina (Footer), el menu, y la
busqueda(Search).Este articulo presenta varias soluciones para una efectiva y eficiente organización
de los componentes de vista (component view). Se evaluara cada solución siguiendo una serie de
criterios especificos detallados mas adelante.

Para explorar las soluciones de plantillas (templates) y de Layout(esquemas), usaremos el


framework Tiles. El "framework Tiles component view" es conodido como tiles. Este framework
usa un archivo de configuración para estos tiles. Este framework no solo te permite reusar tiles, sino
que tambien que permite organizar layouts

Para explorar las soluciones mas poderosas y flexibles, investigaremos la integracion entre Tiles y
Struts.Struts es un framework open source para desarrolar aplicaciones web usando el famoso
modelo MVC (modelo-vista-controlador), el modelo 2 de los patrones de arquitectura. Struts viene
con un conjunto amplio de etiquetas reutilizables, el cual es perfeccionado por la libreria de
etiquetas de Tiles.

Criterio de evaluación.

Evaluaremos cada una de las soluciones basándonos en los siguientes criterios, los criterios no son
mutuamnete excluyentes.Para una situación específica y una aplicación en particula deberemos
elegier enter los pros y los contras de cada soución con respecto a estos factores.

Número de páginas.

La solución debe esforzarse por reducir el numero de páginas the HTML y JSP.El numero de
páginas incrementa la complejidad de desarrollo, de administración y mantenimiento de la
aplicación de una manera drástica.

Repetición de código.

Casi siempre repetir es malo. Cuanto mas código repetido mas díficil es la tarea de desarrollar y
mantener la aplicación.Un siple cambio puede desencadenar una serie de cambios en cascada en
muchas páginas diferentes con consecuencias imprevisibles.Una manera prática de lograr
reusabilidad es eliminando código repetido.

1
http://www.javahispano.com

Control del Layout.

Si repetir código es malo, repetir la logica de layout y código es peor.Esparcir la logica y el


comportamineto de los componentes de la vista ataves de muchas JSP puede ser la receta para un
desastre.Lograr reusar la la plantilla y la logica de de los layout es una forma de reusar, mejor que
solo reusar componentes de vista.

Acoplamiento

El acoplamiento es el grado de interacción entre entidades.Los ingenieros de software han pensado


una y otra vez sobre como minimizar el acoplamiento entre clases no relacionadas, paquetes y
demas. Nosotros podemos aplicar los mismos principios a los componentes de vista.

Complejidad

La complejidad aumenta la díficultad de desarrollo y mantenimiento, haciendo la solución mas


compleja menos satisfactoriaLa complejidad crece rapido y lo que parecia una solución sencilla se
torna rapidamente en un gran enredo teniendo que añadir mas piezas.

Soluciones

Evaluaremos varias soluciones usando ejemplos basicos de JSP con componentes de vista comunes,
como cabecera y piede pagina.Presentaremos estas soluciones segun el orden de complejidad, y
despues las analizaremos segun cada uno de las criterios de de evaluación

Solución 1

Considere el siguiente JSP : a.jsp

<html>

<body>

Header
<p>

a's body...
<p>

Footer
<p>

</body>

</html>

y el siguiente b.jsp

<html>

<body>

Header

2
Struts. Tiles

<p>

b's body...
<p>

Footer
<p>

</body>

</html>

En muchos casos los desarrolladores obtienen el codigo de de los diseñadores de UI y lo convierten


literalmente en JSP, Como podemos ver arriba tenemos las cabecera y los pie de pagina
repetidos.La solución 1 no es deseable por que cambios en un copmonente de vista requiere
cambios de en cada una de las paginas. cada una de las paginas es responsable de colocar (laying
out) sus componentes de vista.Esta solución simple carece de previsión.Con mucho HTML y JSP
repetido, reducimos el el numero de páginas pero a costa de un pesado coste de mantenimeinto.

Solución 2

considere el JSP a.jsp

<html>
<body>

<%-- include header --%>


<jsp:include page="/header.jsp" />

a's body...
<p>

<%-- include footer --%>


<jsp:include page="/footer.jsp" />

</body>
</html>

considere el JSP b.jsp

<html>
<body>

<%-- include header --%>


<jsp:include page="/header.jsp" />

b's body...
<p>

<%-- include footer --%>


<jsp:include page="/footer.jsp" />

</body>
</html>

Note como componentes comunes, como la cabecera y el pie de página, son divididos usando el
mecanismo JSP include

3
http://www.javahispano.com

Considere este header.jsp:

Header
<p>

Considere este footer.jsp:

Header
<p>

La solución 2 soluciona algunas de las limitaciones mayores de la solución 1.Solo se necesita


cambiar los componentes de vista comunes una vez, por tanto, esta solución elimina la duplicidad
de código y simplifica el mantenimiento.Esta solución incrementa un poco el numero de páginas,
pero reduce drásticamentte el numero el firme acoplamiento entre componentes de vistas y otras
páginas.Esta solución es simple y es usaa en muchos aplicaciones reales, sin embargo tiene un
inconveniente, si cambiamos el layout de la aplicación, tendremos que hacerlo en cada página.lo
que se supone un caro y prohibitivo cambio.Esta solución alcanza la reutilización de componentes´,
pero no de las plantillas y dela logica de layout.

Solución 3.

considere a.jsp:

<%@ taglib uri="/WEB-INF/tiles.tld" prefix="tiles" %>

<%@ taglib uri="/WEB-INF/tiles.tld" prefix="tiles" %>

<html>
<body>

<%-- include header --%>


<tiles:insert page="/header.jsp" flush="true"/>

a's body...
<p>

<%-- include footer --%>


<tiles:insert page="/footer.jsp" flush="true"/>

</body>
</html>

y b.jsp:

<%@ taglib uri="/WEB-INF/tiles.tld" prefix="tiles" %>

<html>
<body>

<%-- include header --%>


<tiles:insert page="/header.jsp" flush="true"/>

b's body...
<p>

<%-- include footer --%>


<tiles:insert page="/footer.jsp" flush="true"/>

4
Struts. Tiles

</body>
</html>

La solución 3 usa el mecanismo insert de Tiles, usando esto incluinos el componente de vista en el
sitio correspondiente.En todo los aspectos esta solución es identica a la solución 2, con sus ventajas
y sus desventajas.

Solución 4 Separando el cuerpo

considere el JSP a.jsp

<%@ taglib uri="/WEB-INF/tiles.tld" prefix="tiles" %>

<html>
<body>

<%-- include header --%>


<tiles:insert page="/header.jsp" flush="true"/>

<%-- include body --%>


<tiles:insert page="

<%-- include footer --%>


<tiles:insert page="/footer.jsp" flush="true"/>

</body>
</html>

y este otro b.jsp:

<%@ taglib uri="/WEB-INF/tiles.tld" prefix="tiles" %>

<html>
<body>

<%-- include header --%>


<tiles:insert page="/header.jsp" flush="true"/>

<%-- include body --%>


<tiles:insert page="bBody.jsp" flush="true"/>

<%-- include footer --%>


<tiles:insert page="/footer.jsp" flush="true"/>

</body>
</html>

Esta solución separa el nucleo del cuerpo en su página individual aBody.jsp y bBody.jsp

vea el JSP aBody.jsp:

a's body...
<p>

vea el JSP bBody.jsp:

5
http://www.javahispano.com

b's body...
<p>

Esto limita el cambio del cuerpo a su página y ademas permite reutilizarlo en otras
partes.Eliminando la repetición y la duplicidad.Como las otras soluciones, cada pagina crea todavía
su propio layout. Por tanto aqui tampco tiene una política sobre los layout o esquemas.

Solución 5 Plantillas

Usando la característica de crear plantillas podemos definir los Layouts como plantillas.Dede estos
layouts, podemos insertar marcadores de lugar en vez del actual componente de vista usando la
etiqueta de Tiles insert.Así para todos los componentes esta página define un layout reutilizable.

vea este jsp layout.jsp

<%@ taglib uri="/WEB-INF/tiles.tld" prefix="tiles" %>

<html>
<body>

<%-- include header --%>


<tiles:insert attribute="header"/>

<%-- include body --%>


<tiles:insert attribute="body"/>

<%-- include footer --%>


<tiles:insert attribute="footer"/>

</body>
</html>

Otras paginas de contenido, como a.jsp y b.jsp ussaran el layout anterior para situar los
componentes de vistas.En las paginas actuales insertamos los componentes usando la etiqueta Tiles
insert, Usuando la etiquea Tiles put, podemos especificarel componente de vista actual para todos
los marcadores de lugar.

Considere a.jsp:

<%@ taglib uri="/WEB-INF/tiles.tld" prefix="tiles" %>

<tiles:insert page="/layout.jsp" flush="true">


<tiles:put name="header" value="/header.jsp"/>
<tiles:put name="body" value="/aBody.jsp"/>
<tiles:put name="footer" value="/footer.jsp"/>
</tiles:insert>

Considere b.jsp:

<%@ taglib uri="/WEB-INF/tiles.tld" prefix="tiles" %>

<tiles:insert page="/layout.jsp" flush="true">


<tiles:put name="header" value="/header.jsp"/>
<tiles:put name="body" value="/bBody.jsp"/>
<tiles:put name="footer" value="/footer.jsp"/>
</tiles:insert>

6
Struts. Tiles

La mayor ventaja de esta solución es que encapsula el comportamiento del layout, reduce
drasticamente el acoplamiento del entre los componentes. Sin embarfo incrementa la complejidad
introduciendo otra página para el layout.Entender y implementar el mecanismo de de las plantillas
tambíen puede ser díficil al principio.

Solución 6 Struts y Tiles

La página de layout anterior layout.jsp contiene código HTML y JSP para organizar los
componentes.La páginas a.jsp y b.jsp no contiene código HTML ninguno; estas solo contienen
etiquetas Tiles para insertar los componentes necesarios.No seria agradable especificar todos las
páginas de contenido en un solo archivo XML de configuración?

LLamaremos a este archivo tileDefinitions.xml y especificara las páginas como:

<?xml version="1.0" encoding="ISO-8859-1"?>

<component-definitions>

<definition name="aDef" path="/layout.jsp">


<put name="header" value="/header.jsp"/>
<put name="footer" value="/footer.jsp"/>
<put name="body" value="/aBody.jsp"/>
</definition>

<definition name="bDef" path="/layout.jsp">


<put name="header" value="/header.jsp"/>
<put name="footer" value="/footer.jsp"/>
<put name="body" value="/bBody.jsp"/>
</definition>

<definition name="cDef" path="/layout.jsp">


<put name="header" value="/header.jsp"/>
<put name="footer" value="/footer.jsp"/>
<put name="body" value="/cBody.jsp"/>
</definition>

</component-definitions>

La solución 6 elimina todas las páginas de contenido a.jsp, b.jasp... poniendo sus definiciones en un
archivo XML. Pero si no existe un recurso llamado a.jsp, como podemos solicitarlo? Y mas
importante como podemos acceder al archivo XML tileDefinitions.xml.La integracion entre Strust y
Tiles lo permite. Ademas la configuración uniforme de parametros de Struts, nos permitira
especificar el archivo de configuración como otro parametro en el web.XML, como mostramos
abajo. Especificando el parametro definition-config posibilita a Struts encontrar y conocer acerca de
la definición Tiles.

<!-- Standard Action Servlet Configuration (with debugging) -->


<servlet>
<servlet-name>action</servlet-name>

<!--
<servlet-class>
org.apache.struts.action.ActionServlet
</servlet-class>
-->

7
http://www.javahispano.com

<servlet-class>
org.apache.struts.tiles.ActionComponentServlet
</servlet-class>

<init-param>
<param-name>definitions-config</param-name>
<param-value>
/WEB-INF/tileDefinitions.xml
</param-value>
</init-param>
...
<!-- Mapeado Estandard del Action Servlet -->
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
...
</servlet>

ahora definimos una acción Struts, la cual devuelve una definición especifica del archivo de
configuración con el valor éxito

package com.malani.struts.action;

import org.apache.struts.action.*;
import javax.servlet.http.*;

public class DoFirst extends Action {

public ActionForward perform(


ActionMapping aMapping,
ActionForm aForm,
HttpServletRequest aRequest,
HttpServletResponse aResponse
) {
return aMapping.findForward("success");
}

No podemos invocar un definición directamente desde el navegador, pero puedes invocar una desde
Struts, como si esta fuese un recurso actual.Definimos las acciones struts en el archivo struts-
config.xmlcomo vemos abajo.

<action path="/a" type="com.malani.struts.action.DoFirst">


<forward name="success" path="aDef"/>
</action>

<action path="/b" type="com.malani.struts.action.DoFirst">


<forward name="success" path="bDef"/>
</action>

<action path="/c" type="com.malani.struts.action.DoFirst">


<forward name="success" path="cDef"/>
</action>

Ahora invocamos la acción Struts solicitando a.do y b.do respectivamente para devolvernos el
recurso deseado.

8
Struts. Tiles

La solución 6 tiene la ventaja de establecer todas las definiciones en un archivo de configuración


XML, reduce el numero de páginas. Pero al introducir Struts aumenta notablemente el grado de
complejidad.

Solución 7 Herencia en Tiles.

En el aarchivo de configuración que todas las definiciones de las páginas son parecidas. Estas
definen tres componentes , cabecera cueropo y pie de página, de las cuales dos de ellas (la cabecera
y el pie de página) son siempre iguales. Una poderosa caracteristica de Tiles es la herencia entre
definiciones. Por tantopodemos crear una definición base y dejoar que las demas hereden de esta.La
definición base solo debe suministrar la características. La definición hija solo debe definir sus
componentes unicos.Enseñaremos el siguiente codigo para observar como se usa la herencia en el
archivo de configuración XML.

<?xml version="1.0" encoding="ISO-8859-1"?>

<component-definitions>

<definition name="baseDef" path="/layout.jsp">


<put name="header" value="/header.jsp"/>
<put name="footer" value="/footer.jsp"/>
<put name="body" value=""/>
</definition>

<definition name="aDef" extends="baseDef">


<put name="body" value="/aBody.jsp"/>
</definition>

<definition name="bDef" extends="baseDef">


<put name="body" value="/bBody.jsp"/>
</definition>

<definition name="cDef" extends="baseDef">


<put name="body" value="/cBody.jsp"/>
</definition>

</component-definitions>

Esto elimina parte del codigo repetido.

Resumen de soluciones

La siguiente tabla resume las distintas soluciones y sus caracteristicas respecto a cada uno de los
criterios de evaluación, existen mas criterios como la extensibilidad, la mantenibilidad o el
rendimiento.

Solution Paginas Repeticion LayoutControl Acoplamiento Complejidad

1: Basic * *** * *** *

2: include ** ** * ** *

3: insert ** ** * ** *

4: separar *** ** ** ** **

9
http://www.javahispano.com

5: Plantillas *** * *** * **

6: S. & Tiles ** * *** * ***

7: T Herencia ** * *** * ***

Escala: Alto: *** Medio: ** Bajo: *

Observamos que el grado de complejidad va creciendo segun avanzamos en las soluciones, al igual
que el control del layout, sin embargo tanto la repeticioón de código como el acoplamiento
desciende.

Que solución es la mejor?

La mejor solución depende de las necesidades del proyecto y sus reqerimientos y de tus habilidades
y conocimientos en el desarrollo y mantenimiento de aplicaciones web. La solución basica es
demasiado simple.No es recomendable porque va en contra de los principios de las buenas practicas
de la ingeniería del software, Si ya estamos usando Struts entonces podremos aprvecharnos de la
infuencia del la integración de Tiles y Struts, para crear una poderosa solución.

Resumen

En este articulo, hemos examinado varias soluciones para organizar componentes de vista en
HTML y JSP. Hemos explorado la unión entre Tiles y Struts. Estas estrategias y soluciones pueden
ayudarnos a hacer un tomar decisiones arquitectonicas con respecto a nuestras aplicaciones Web.

Pedro del Gallego Vida, Akuma, estudiante de Ingeniería Superior en Informática en Madrid, centra su interés
profesional en la POO, la programación declarativa/lógica, la inteligencia articfial y la teoría del conocimiento.
Actualmente se deja el tiempo intentando desarrollar un framework para la simulación de redes neuronales y
memorias Hopfield.
Para cualquier duda o comentario: akipelli_ARROBA_hotmail.com

10

También podría gustarte