viernes, 5 de julio de 2013

Personalizar las páginas de error (404, 500, ...) en Apache Tapestry

Apache Tapestry
Al desarrollar una aplicación y sobre todo si se trata de una página web pública a la que puede acceder cualquier usuario de internet es casi obligatorio hacer que las páginas de los diferentes códigos de error HTTP tenga el mismo estilo que el resto de las páginas de la aplicación y con el contenido que queramos indicar al usuario para que sepa porque se ha producido ese error y que puede hacer.

En Tapestry se puede redefinir la página de cualquier error HTTP, los más habituales son la del código de error 404 que es la de una página no encontrada o la del código de error 500 que es la página que se mostrará cuando se haya producido un error en el servidor.

Lo que hay que añadir para tener estas páginas personalizadas es un poco de xml en el archivo descriptor de la aplicación web (web.xml) y crear las propias páginas con el contenido que deseemos.

El código xml que debemos añadir es el siguiente:

<filter-mapping>
<filter-name>app</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
...
<error-page>
<error-code>404</error-code>
<location>/error404</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error500</location>
</error-page>
view raw web.xml hosted with ❤ by GitHub

En él indicamos que el filtro de Tapestry se encargue también de gestionar las páginas de los códigos de error y más tarde indicamos cuales son sus URL.

Una vez modificado el archivo web.xml deberemos crear las páginas personalidazas, no es diferente de cualquier otra página pero algo que nos puede interesar es distinguir si estamos en el modo producción o en el modo desarrollo para sacar más o menos información. En desarrollo nos puede ser útil disponer de esa información adicional. El símbolo SymbolConstants.PRODUCTION_MODE nos indica si estamos en modo producción y lo podemos configurar de diferentes formas, una de ellas es como un a contribución en el módulo de la aplicación.

public static void contributeApplicationDefaults(MappedConfiguration<String, Object> configuration) {
configuration.add(SymbolConstants.PRODUCTION_MODE, false);
...
}
view raw AppModule.java hosted with ❤ by GitHub
package es.com.blogspot.elblogdepicodev.tapestry.jpa.pages;
import org.apache.tapestry5.SymbolConstants;
import org.apache.tapestry5.annotations.Import;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.ioc.annotations.Symbol;
import org.apache.tapestry5.services.Request;
@SuppressWarnings("unused")
public class Error404 {
@Property
@Inject
private Request request;
@Property
@Inject
@Symbol(SymbolConstants.PRODUCTION_MODE)
private boolean productionMode;
}
view raw Error404.java hosted with ❤ by GitHub
<!DOCTYPE html>
<html t:type="layout" titulo="Página o recursos no encontrado" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd" xmlns:p="tapestry:parameter">
<div>
<h1 class="error">Página o recurso no encontrado</h1>
<h7> <a href="http://en.wikipedia.org/wiki/List_of_HTTP_status_codes" target="_blank">Error 404</a> </h7>
<p>
Oooops! Parece que lo que estás buscando ya no se encuentra en su sitio prueba a encontrarlo desde la <a t:type="pageLink" page="admin/producto">página Inicio</a>.
</p>
<t:if test="!productionMode">
<div>
<h2>Información</h2>
<t:renderobject object="request" />
</div>
</t:if>
</div>
</html>
view raw Error404.tml hosted with ❤ by GitHub

La página de cualquier otro código de error HTTP sería similar a esta. Si quisiéramos mostrar una página de un código de error en la lógica de un componente debemos devolver en el manejador de evento un objeto HttpError:

return new HttpError(HttpServletResponse.SC_NOT_FOUND, "Página no encontrada");
return new HttpError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR , "Se ha producido un error");

Esta es una captura de pantalla de la página 404 con la aplicación en modo desarrollo.



Para finalizar la página de error 500 en Tapestry es diferente de la página cuando se produce una excepción en el servidor. Cuando se produce un excepción y no se controla de alguna forma Tapestry muestra la página ExceptionReport que explicaré como personalizar en otra entrada y que no es diferente de lo visto aquí.

Como en el resto de entradas el código fuente completo lo puedes encontrar en mi repositorio de GitHub. Si quieres probarlo en tu equipo lo puedes hacer de forma muy sencilla con los siguientes comandos y sin instalar nada previamente (salvo java y git). Si no dispones de git para clonar mi repositorio de GitHub puedes obtener el código fuente del repositorio en un archivo zip con el anterior enlace.


$ git clone git://github.com/picodotdev/elblogdepicodev.git
$ cd elblogdepicodev/TapestryJPA
$ ./gradlew tomcatRun
view raw git.sh hosted with ❤ by GitHub
Referencia:
Documentación sobre Apache Tapestry