Estructura de una Aplicación REST sobre Cetia4
Parte 2: Página Principal de la Aplicación y Layout
Este documento desglosará la estructura de la página principal de la aplicación, y del manejo de layout que se realiza en ésta - y todas las demás páginas - por medio de las facilidades definidas por la librería OpenSymphony SiteMesh. .
![]() |
La página principal de la aplicación forum simplemente despliega un mensaje de bienvenida.
![]() |
Definición de la Página Principal
Esta página se construye a partir del servlet predefinido com.acsinet_solutions.cetia4.controller.rest.support.MainServlet, que se registra como servlet principal ( el primer servlet mostrado en el breadcrumb ), y despliega la página index.jsp.
![]() |
El registro de este servlet en el web deployment descriptor /WEB-INF/web.xml es el siguiente:
<servlet>
<description>
Main Controller. Redirects to /WEB-INF/html/main/index.jsp
or /WEB-INF/xml/main.index.jspx
</description>
<servlet-name>main</servlet-name>
<servlet-class>
com.acsinet_solutions.cetia4.controller.rest.support.MainServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>main</servlet-name>
<url-pattern>/main</url-pattern>
</servlet-mapping>
Nótese como cada uno de los elementos mostrados en la imagen anterior están definidos en este listado.
Además, se configura el elemento <load-on-startup> con valor en 1 para que este servlet se registre al iniciar la aplicación, y de esta manera siempre aparezca al inicio del breadcrumb.
El servlet predefinido MainServlet siempre avanzará la petición a la página index.jsp, cuya ruta se construye de acuerdo al tipo de petición realizada ( web, web service ) y al nombre del servlet como se mostró en la imagen anterior.
En este caso el contenido de esta página ( /WEB-INF/html/main.index.jsp ) es muy simple:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib
uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%@ taglib uri="http://acsinet-solutions.com/cetia" prefix="cetia"%>
<%@ taglib uri="http://acsinet-solutions.com/pager" prefix="pager"%>
<cetia:init/>
<html>
<head>
<title>Hello World</title>
</head>
<body>
Hello World!
</body>
</html>
Todas las declaraciones iniciales en esta página definen tag libraries que hasta el momento no se utilizan, pero podrían utilizarse en algún momento dado si se definiera contenido más complejo. En realidad, lo único que se hace en esta página JSP es desplegar un mensaje de bienvenida ( Hola Mundo! ).
Layout
Al igual que el resto de las páginas de la aplicación, esta pantalla principal cuenta con barras de encabezado, pie de página y menú de opciones.
![]() |
Es a través de este menú de opciones se tiene navegabilidad hacia el resto de la funcionalidad de la aplicación. Estas barras adicionales no forman parte de cada página individual de la aplicación, de lo contrario, se tendría una buena cantidad de código repetido por página - lo cual dificulta enormemente el mantenimiento de la aplicación web.
![]() |
En lugar de ello se hace uso de un filtro ( Servlet Filter ) para agregar layout a las páginas de la aplicación. Este filtro es proporcionado por la librería Open Source SiteMesh. El filtro intercepta todas las peticiones que regresan contenido HTML y las decora.
![]() |
El filtro de SiteMesh se configura a través del web deployment descriptor /WEB-INF/web.xml, de un archivo de configuración adicional /WEB-INF/decorators.xml, y de las páginas JSP que definen el contenido que será desplegado como layout. La siguiente imagen resume esta configuración:
![]() |
La declaración del filtro en el web deployment descriptor /WEB-INF/web.xml es como sigue:
<filter>
<filter-name>sitemesh</filter-name>
<filter-class>
com.opensymphony.module.sitemesh.filter.PageFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>sitemesh</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Con esto se aplica el filtro a cualquier petición de entrada a la aplicación web. Sin embargo, solamente las peticiones HTML serán decoradas, no las peticiones XML, de imagen ni de otro tipo. Esta distinción es realizada por el filtro de forma automática, sin tener que definir ninguna configuración adicional para ello.
El archivo JAR de SiteMesh debe encontrarse bajo el directorio /WEB-INF/lib para que pueda funcionar. Internamente, este archivo hace referencia a la configuración del filtro bajo /WEB-INF/decorators.xml. El contenido de este archivo se muestra a continuación:
<?xml version="1.0" encoding="ISO-8859-1"?>
<decorators defaultdir="/WEB-INF/layouts">
<excludes>
<pattern>/css/*</pattern>
<pattern>/img/*v/pattern>
<pattern>/scripts/*</pattern>
<pattern>/index.jsp</pattern>
<pattern>/jlogin.jsp</pattern>
<pattern>/construction.jsp</pattern>
<pattern>/confirmation*</pattern>
</excludes>
<decorator name="internal_layout" page="internal_layout.jsp">
<pattern>/*</pattern>
</decorator>
</decorators>
Básicamente aquí se definen varias cosas. Una de ellas es el listado de una serie de patrones a los cuales no se aplicará el decorado. Por otro lado también se indica la página JSP que define el layout por defecto: /WEB-INF/layouts/internal_layout.jsp.
SiteMesh es muy flexible y permite definir más de un decorador, que puede aplicarse dependiendo de etiquetas <META> en los archivos que van siendo decorados, sin embargo, aquí se muestra el escenario más sencillo y típico. Otros tutoriales se escribirán posteriormente para describir características de configuración más avanzadas sobre SiteMesh.
El contenido del archivo internal_layout.jsp es el siguiente:
<%@ taglib uri=
"http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %>
<%@ taglib uri="http://www.opensymphony.com/sitemesh/page" prefix="page" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://acsinet-solutions.com/cetia" prefix="cetia"%>
<%@ taglib uri="http://acsinet-solutions.com/nav" prefix="nav"%>
<%@ taglib tagdir="/WEB-INF/tags" prefix="tags" %>
<cetia:init writeScripts="true"/>
<%-- Calendar Script for dateField tags --%>
<html>
<head>
<title><decorator:title default="Título"/></title>
<link rel="stylesheet" href="${ _portal_path }/css/style.css">
<decorator:head/>
</head>
<body>
<table id="pagina">
<tr>
<td colspan="2">
<div align="center" class="breadcrumb">
<%@include file="/WEB-INF/layouts/header.jspf"%>
</div>
</td>
</tr>
<tr>
<td width="100" align="center" rowspan="2" id="menus">
<%@include file="/WEB-INF/layouts/menu.jspf"%>
</td>
<td width="700" id="contenido">
<div align="center">
<nav:breadcrumb/>
</div>
<hr width="80%" size="3">
<div align="center">
<tags:messages/>
<%-- /WEB-INF/tags/messages.tag --%>
<br>
<decorator:body/> <%-- The content page --%>
<br>
<hr width="80%" size="3">
</div>
</td>
</tr>
<tr>
<td>
<div align="center" class="breadcrumb">
<%@include file="/WEB-INF/layouts/footer.jspf"%>
</div>
</td>
</tr>
</table>
</body>
<head>
<META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">
</head>
</html>
Básicamente lo que se hace como parte de este archivo es construir la estructura de cada página que se va a desplegar. El contenido del encabezado, menú y footer se leen a partir de archivos .jspf ( fragmentos JSP ) externos con el fin de hacer el mantenimiento del código más sencillo. Estos fragmentos se incluyen en esta página a través de directivas como la siguiente:
<%@include file="/WEB-INF/layouts/header.jspf"%>
Por otro lado, existen varios fragmentos en la página anterior que pueden resultar interesantes. Se enumeran a contínuación algunos de ellos:
<cetia:init writeScripts="true"/>
Esta declaración de define casi al inicio del archivo, justo después de la declaración de los tag libraries. Con esto se define el atributo de página _portal_path, y además se indica que se incluyan los scripts que se manejan en otras etiquetas de Cetia4. Estos scripts se buscan por defecto bajo el directorio scripts/ de la aplicación web actual. De esta manera, nos aseguramos que todas las páginas puedan trabajar con los componentes de fecha y hora que hacen uso de dichos scripts.
<title><decorator:title default="Título"/></title>
La etiqueta <decorator:title/> permite escribir el título de la página HTML que está siendo decorada. De esta manera, cada página podrá desplegar su propio nombre en la barra de título del navegador.
![]() |
<link rel="stylesheet" href="${_portal_path}/css/style.css">
Agrega la hoja de estilo general que compartirán todas las páginas. El atributo _portal_path es creado a nivel página mediante la etiqueta <cetia:init>. Por defecto, dicha variable se inicializa al valor del context path de la aplicación, pero este valor puede ser cambiado especificando el parámetro de inicio de contexto com.acsinet_solutions.cetia4.portal_path en el web deployment descriptor /WEB-INF/web.xml:
<context-param>
<param-name>com.acsinet_solutions.cetia4.portal_path</param-name>
<param-value>/common</param-value>
</context-param>
Esta puede ser una manera práctica de definir una ruta común para definir recursos estáticos comunes a más de una aplicación web en un contenedor.
Por otro lado, si no se quiere utilizar esta variable, se puede cambiar el uso de la misma en el código anterior por ${pageContext.request.contextPath}.
<decorator:head/>
Si la página que se incluye define encabezados adicionales como parte de su bloque <head>, éstos pueden ser integrados a la página final por medio de esta etiqueta. Dichos encabezados pueden ser scripts, etiquetas <meta>, hojas de estilo adicionales, etc.
![]() |
<nav:breadcrumb/>
Define el breadcrumb para la aplicación.
![]() |
Los textos del breadcrumb se obtienen a partir de las llaves “stage_view” definidas en la colección de archivos /WEB-INF/classes/web_messages*.properties. Este resource bundle se configura en el archivo /WEB-INF/web.xml utilizando la siguiente llave:
<context-param>
<description>
Resource bundle used by default by JSTL format tags
</description>
<param-name>
javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
<param-value>web_messages</param-value>
</context-param>
El nombre de cada vista ( view ) se despliega en el breadcrumb en caso de que la colección de archivos mencionados con anterioridad no hayan sido creados, o que las llaves correspondientes a cada vista no hayan sido definidos en dichos archivos.
Para mayor información al respecto, consultar el tópico de navegación en el tutorial de Cetia4.
<tags:messages/>
Hace referencia a un tag file que despliega los mensajes generales y de validación de la aplicación. La referencia al tag file se configura al inicio del archivo como:
<%@ taglib tagdir="/WEB-INF/tags" prefix="tags" %>
El cual hace referencia al directorio /WEB-INF/tags, dentro del cual existe el archivo messages.tag. El contenido de este archivo es el siguiente:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://acsinet-solutions.com/cetia" prefix="cetia"%>
<c:if test="${ _message != null }">
<br>
<div align="center">
<table border="1" cellpadding="20">
<tr>
<td class="message">
${ _message }
</td>
</tr>
</table>
</div>
<br>
</c:if>
<c:catch var="other">
<c:if test="${ _validation_exception != null }">
<div align=left class="message">
<br>
${ _validation_exception.message }
<ul>
<cetia:forEachIssue var="issue">
<li>${ issue }
</cetia:forEachIssue>
</ul>
</div>
</c:if>
</c:catch>
<c:if test="${ other != null }">
<c:out value="${ _validation_exception.issues }"/>
</c:if>
Con ello se desplegarán mensajes y errores de validación asociados a la página. Los mensajes generales se almacenan por parte del framework utilizando la llave _message, y las exceptiones de validación se almacenan por medio de la llave _validation_message. Para mayor información al respecto, consultar el tópico de navegación en el tutorial de Cetia4.
Como este tag se encuentra definido a nivel layout, funcionará independientemente de cuál sea la página que se encuentre desplegada actualmente.
<decorator:body>
Define la sección del documento donde se integrará el cuerpo del documento que está siendo decorado. Unicamente la sección de dicho documento que se encuentra entre las etiquetas <body> y </body> es insertada en esta posición por la librería SiteMesh.
![]() |
Menú
La página de menú se encuentra implementada por el archivo /WEB-INF/layouts/menu.jspf. El contenido de este archivo es el siguiente:
<table>
<tr>
<th>FORUM</th>
</tr>
<tr>
<td><p>
<a href="${ pageContext.request.contextPath }
/topics?_root=1" >topics</a>
</p></td>
</tr>
<tr>
<td><p>
<a href="${ pageContext.request.contextPath }
/topic_types?_method=catalog&_root=1"
>topic types</a>
</p></td>
</tr>
</table>
Aquí básicamente se implementa una tabla con ligas hacia las páginas de tópicos y tipos de tópico. Lo único que quizás sea relevante en estas ligas es que contienen el parámetro _root=1, con lo que se evita que al seleccionar alguna ellas, la selección se sigua apilando en el breadcrumb; en lugar de ello, el breadcrumb se limpiará cuando se haga alguna selección de estas opciones. Para mayor información al respecto, consultar el tópico de navegación en el tutorial de Cetia4.
Regresar
Derechos Reservados de este Material:
Atribución-No Comercial-Licenciamiento Recíproco 2.5 México
http://creativecommons.org/licenses/by-nc-sa/2.5/mx/
Eres libre de: a) copiar, distribuir y comunicar públicamente la obra, b) hacer obras derivadas. Bajo las condiciones siguientes: a) Atribución. Debes reconocer la autoría de la obra en los términos especificados por el propio autor o licenciante. b) No comercial. No puedes utilizar esta obra para fines comerciales. c) Licenciamiento Recíproco. Si alteras, transformas o creas una obra a partir de esta obra, solo podrás distribuir la obra resultante bajo una licencia igual a ésta.
Al reutilizar o distribuir la obra, tiene que dejar bien claro los términos de la licencia de esta obra. Alguna de estas condiciones puede no aplicarse si se obtiene el permiso del titular de los derechos de autor. Nada en esta licencia menoscaba o restringe los derechos morales del autor.
Java and all Java-based trademarks and logos are trademarks of Sun Microsystems in the United States and/or other countries.
Other products and services are trademarks of their respective owners.
|
















