Skip to content


Woodstock y Facelets una convivencia extraña

En el último proyecto en el que estuve trabajando tome la decisión de hacer uso la librería de componentes JSF, Woodstock. Antes de comenzar el desarrollo pensé en hacer uso de una librería para el desarrollo de templates compatible con JSF. Pensé en Struts Tiles y Facelets y tras un rato evaluándolos(basándome en mi experiencia con cada uno) me decante por Facelets por varios motivos:

  • No se tiene que configurar cada página en el tiles-conf. Es cierto puede ser una tontería pero la razón de peso para mi es que, este oculta e incrementa el tiempo necesario para la compresión de proyectos que ya están desarrollados.
  • Solo se hace uso de una tecnología (JSF), lo cual para mi es una razón de peso. A mayor número de tecnologías usadas, mayor es la complejidad y la dificultad de compresión del proyecto web y claro esta en el desarrollo de aplicaciones web ya intervienen unas cuantas de tecnologías como para complicarlo más.
  • El trabajo con Facelets se asimila mucho al uso de templates con XSLT (en lo cual me siento muy cómodo). Dispones de elementos como ui:composion en vez de xsl:call-templates, y xsl:apply templates y siempre conoces que ficheros de templates usa tu página.

Tras descargarme las últimas versiones de ambas librerías, la configuración no fue un problema ya que solo debemos agregar estas lineas a nuestro web.xml para configurar el gestor de temas de Woodstock y el filtro de subida de ficheros:

<filter>
<filter-name>UploadFilter</filter-name>
<filter-class>com.sun.webui.jsf.util.UploadFilter</filter-class>
<init-param>
<param-name>maxSize</param-name>
<param-value>1000000</param-value>
</init-param>
<init-param>
<param-name>sizeThreshold</param-name>
<param-value>4096</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>UploadFilter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>

<servlet>
<servlet-name>ThemeServlet</servlet-name>
<servlet-class>com.sun.webui.theme.ThemeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ThemeServlet</servlet-name>
<url-pattern>/theme/*</url-pattern>
</servlet-mapping>

Y en el caso de Facelets que es un poco más complejo solo necesitamos agregar los siguientes parámetros de configuración al web.xml:

<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.xhtml</param-value>
</context-param>
<context-param>
<param-name>facelets.DEVELOPMENT</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>facelets.SKIP_COMMENTS</param-name>
<param-value>true</param-value>
</context-param>

Y el siguiente manejador de vistas al faces-config.xml:

<application>
<view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
</application>

Con esto habremos configurado todo lo necesario y los que uséis NetBeans no tendréis ni que configurar esto ya que durante la creación de vuestro proyecto Web una vez seleccionados los frameworks JSF y Facelets esta configuración sera agregada. Por norma las configuraciones de JSF suele disponer de un mapeo del servlet sobre /faces/* o *.jsf, si os fijáis en el parámetro javax.faces.DEFAULT_SUFFIX mapea *.xhtml. ¿Qué significa esto?:

  1. Todas las peticiones que vayan contra un fichero con extensión *.xhtml serán usadas como ficheros de templates.
  2. Todas las peticiones que vayan contra un fichero con extensión *.jsf (si usaste esta configuración) o estén en la ruta /faces/* (si usaste esta) serán tratados como páginas JSF normales.

El resto de parámetros de como facelets.DEVELOPMENT para mostrar los errores y trazas vía web (para esto ya tenemos una bonita consola en nuestro IDE) y facelets.SKIP_COMMENTS (se salta cualquier comentario sin tratarlo) no son de importancia (de hecho podemos trabajar sin ellos ya que disponen de configuración por defecto en la librería). Bien ahora viene lo interesante, creamos un fichero template.xhtml con el siguiente contenido en el raíz de nuestro sitio web:

<f:view xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:jsp="http://java.sun.com/JSP/Page" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:webuijsf="http://www.sun.com/webui/webuijsf">
<webuijsf:page>
<webuijsf:html>
<webuijsf:head>
<f:facet name="title">
<ui:insert name="title">Titulo por defecto</ui:insert>

</f:facet>
</webuijsf:head>
<webuijsf:body>
<webuijsf:form id="indexForm">
<ui:insert name="body">Cuerpo por defecto</ui:insert>
</webuijsf:form>
</webuijsf:body>
</webuijsf:html>
</webuijsf:page>
</f:view>

Y otro fichero index.jsp con:

<?xml version="1.0" encoding="UTF-8"?>
<jsp:root version="2.0" xmlns:jsp="http://java.sun.com/JSP/Page" xmlns:ui="http://java.sun.com/jsf/facelets">
<ui:composition template="/template.xhtml">
<ui:define name="title">Texto de titulo</ui:define>
<ui:define name="body">Texto de cuerpo</ui:define>
</ui:composition>
</jsp:root>

Paso a describiros que es lo que hacemos en cada fichero:

  1. template.xhtml: Este fichero es la plantilla y dispone de una vista de JSF en la que agregamos el cuerpo de nuestra pagina que como se observa hace uso de los tags de Woodstock. En determinadas posiciones como son el título de la página agregamos las etiquetas ui:insert con un nombre que más tarde usaremos para remplazar su contenido.
  2. index.jsp: En el disponemos de una llamada ui:composion con el atributo template apuntando a nuestro fichero de template template.xhtml. Seguidamente dispone de ui:define apuntando a los ui:insert de nuestro fichero template.xhtml(igual que un xsl:call-template con sus xsl:param) y con los nuevos valores(no tiene por que ser texto puede ser etiquetado JSF).

Como se observa lo que conseguimos de este modo es disponer de un cuerpo único para todas nuestra páginas. Algo importante al respecto de Facelets es que se permiten realizar ui:define en nuestro ficheros jsp a atributos que estan en otros ui:composion de nuestro template, esto quiere decir que podemos combinar varios templates a través de llamadas ui:composion e insertar solo las partes que nos hacen falta.

La convivencia

El uso conjunto de Facelets y Woodstock cambia los atributos del segundo. ¿Que quiere decir esto?, pues que si creamos por ejemplo:

  • Un webuijsf:button este deberá usar atributos action en vez de actionExpression.
  • Un webuijsf:upload deberá disponer de un atributo value en vez de un fileUploaded y además obligara a insertar un enctype=”multipart/form-data” en nuestro webuijsf:form para que funcione.

Solo puedo deciros que el proyecto Woodstock tiene modificada su API (estos atributos que cambian están marcados como DEPRETATED) y que cuando trabaja con Facelets estos cambian (Un par de horas o tres me dan la razón :P ). Podéis descargaros el proyecto de NetBeans (se necesitan los plugins Visual Web JSF Components y Facelets para disponer de las librerías) aquí. Espero que os sirva de algo.  :)

Posted in Desarrollo. Tagged with , , , .

0 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.