JSTL 1.0. Estandarizando JSP.

JSTL responde a la demanda de los desarrolladores de un conjunto de acciones JSP personalizadas para manejar las tareas que necesitan casi todas las pginas JSP, incluyendo procesamiento condicional, internacionalizacin, acceso a bases de datos y procesamiento XML. Esto acelarar el desarrollo de JSPs ms o menos eliminando la necesidad de elementos de scripting y los inevitables y difciles de encontrar errores de sintaxis, y liberando el tiempo anteriormente gastado en desarrollar y aprender trillones de acciones personalizadas especficas del proyecto para estas tareas comunes.

Este tutorial nos ensea cmo JSTL puede simplificar nuestra vida cuando usamos JSP, en grandes y pequeas aplicaciones. En este tutorial se ofrecer una introduccin a JSTL y mostrar como usar las acctiones JSTL ms comunes.

.Introduccin a las Libreras JSTL

JSTL 1.0 especifica un conjunto de libreras de etiquetas basadas en el API JSP 1.2. Hay cuatro libreras de etiquetas independientes, cada una contiene acciones personalizadas dirigidas a un rea funcional especfica. Esta tabla lista cada librera con su prefijo de etiqueta recomendado y la URI por defecto:

Descripcin Prefijo URI por Defecto
Core c http://java.sun.com/jstl/core
XML Processing x http://java.sun.com/jstl/xml
I18N & Formatting fmt http://java.sun.com/jstl/fmt
Database Access sql http://java.sun.com/jstl/sql

La Librera Core contiene acciones para las tareas rutinarias, como incluir o excluir una parte de una pgina dependiendo de una condicin en tiempo de ejecucin, hacer un bucle sobre una coleccin de tems, manipular URLs para seguimiento de sesin, y la correcta interpretacin del recurso objetivo, as como acciones para importar contenido de otros recursos y redireccionar la respuesta a una URL diferente.

La Librera XML contiene acciones -- como puedes imaginar -- para procesamiento XML, includo validar un documento XML y transformarlo usando XSLT. Tambin proporciona acciones para extraer parte de un documento XML validado, hacer bucles sobre un conjunto de nodos, y procesamiendo condicional basado en valores de nodos.

La Internationalizacin (i18n) y el formateo general estn soportados por las acciones de la Librera I18N & Formatting. Podemos leer y modificar informacin almacenada en una base de datos con las acciones proporcionadas por la Librera Database Access.

Ms adelante, podemos esperar que todos los contenedores Web incluyan una implementacin de las libreras JSTL, as no tendremos que instalar ningn cdigo adicional. Hasta que esto suceda, podemos descargar e instalar la implementacin de referencia (RI) de JSTL. Se ha desarrollado dentro del proyecto Apache Taglibs como una librera llamada Standard. Puedes bajarla desde aqu:The JSTL RI: the Standard Library at Apache Taglibs.

Instalar RI es fcil, slo hay que copiar los ficheros JAR del directorio lib de la distribucin al directorio WEB-INF/lib de nuestra aplicacin. Observa que JSTL 1.0 requiere un contenedor JSP 1.2, debemos asegurarnos de tener un contenedor compatible con JSP 1.2 antes de probar esto.

Para usar una librera JSTL, tanto si la implementacin est incluida con el contenedor o con el RI, debemos declarar la librera usando una directiva taglib, como lo haramos con una librera de etiquetas personalizadas normal:

<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>

Observa que siempre deberamos usar la URI por defecto, incluso aunque la especificacin JSP nos permita sobreescribirla. Un contenedor puede generar cdigo optimizado para la accin JSTL en la clase correspondiente a una pgina JSP. Esto puede resultar en un mejor rendimiento que cuando el cdigo generado llama a los manejadores de etiquetas a travs del API estndar. Sin embargo, slo cuando se usa la URI por defecto, es cuando el contenedor puede utilizar una implementacin optimizada.

.El Lenguaje de Expresin JSTL

Adems de las libreras de etiquetas, JSTL 1.0 define un llamado Lenguaje de Expresiones (EL). EL es un luenguaje para acceder a datos de varias fuentes en tiempo de ejecucin. Su sintaxis es considerablemente ms amigable que la de Java, que es el nico lenguaje soportado directamente por la especificacin JSP 1.2. Todas las acciones JSTL reconocen expresiones EL en sus valores de atributos, y se podran desarrollar acciones personalizadas para que hicieran lo mismo. Se espera que EL sea incorporado dentro de la prxima versin de la especificacin JSP para mejorar su uso para acceder a datos sobre el lenguaje Java. Si es as, podremos usar expresiones EL en un valor de atributo de una accin, o incluso en una plantilla de texto.

Si has usado JavaScript deberas sentirte como en casa con EL. EL toma prestada de JavaScript la sintaxis para acceder a estructuras de datos tanto como propiedades de un objeto (con el operador .) como con elementos con nombres de un array (con el operador ["nombre"]). Las propiedades de los componentes JavaBeans y las entradas java.util.Map, que usan la clave como nombre de propiedad, pueden ser accedidas de esta forma. Aqu tenemos algunos ejemplos:


${myObj.myProperty}$
${myObj["myProperty"]}$
${myObj[varWithTheName]}$

Como se ve aqu, una exprein EL siempre debe estar encerrada entre los caracteres ${ y }$. Las dos primera expresiones acceden a una propiedad llamada myProperty en un objeto representado por una variable llamada myObj. La tercera expresin acceder a una propiedad con un nombre contenido en un variable, esta sintaxis se puede utilizar con cualquier expresin que evale el nombre de la propiedad.

El operador de acceso a array tambin se usa para datos representados como una coleccin de elementos indexados, como un array Java o una java.util.List:


${myList[2]}$
${myList[aVar + 1]}$

Adems de los operadores de propiedad y elemento array y los operadores aritmticos, relacionales, y lgicos, hay un operador especial para comprobar si un objeto est "vaco" o no puede ser usado en una expresin EL. La siguiente tabla lista todos los operadores:

OperadorDescription
.Accede a una propiedad
[]Accede a un elemento de un array/lista
()Agrupa una subexpression
+Suma
-Resta o negacin de un nmero
/ o divDivisin
% o modMdulo (resto)
== o eqComprueba Igualdad
!= o neComprueba desigualdad
< o ltComprueba menor que
> o gtComprueba mayor que
<= o leComprueba menor o igual que
>= o gtComprueba mayor o igual que
&& o andComrpueba AND lgico
|| o orComprueba OR lgico
! o notComplemento binario booleano
emptyComprueba un valor vaco (null, string vaco, o una colleccin vaca)

Lo que no encontraremos en EL son sentencias como asignaciones, if/else, o while. Para este tipo de funcionalidades en JSP se usan los elementos Action, y EL no est pensado para utilizarse como un lenguaje de programacin de propsito generar, slo un lenguaje de acceso a datos.

Por supuesto, los literales y las variables, tambin son parte del lenguaje. EL proporciona los siguientes literales, similares a los que proporcionan JavaScript, Java, y otros lenguajes similares:

Tipo de Literal Descripcin
String Encerrado con comillas simples o dobles. Una comilla del mismo tipo dentro del string puede ser escapada con una barra invertida: (\' en un string encerrado con comillas simples; \" en un string encerrado con comillas dobles). El caracter de barra invertida debe se escapado como \\ en ambos casos.
Integer Un signo opcional (+ o -) seguido por digitos entre 0 y 9.
Coma Floating Lo mismo que un literal entero, excepto que usa un punto como separador de la parte fraccional y que se puede especificar un exponente con e o E, seguido por un literal entero.
Boolean true o false.
Null null.

Cualquier objeto en uno de los mbitos de JSP (pgina, solicitud, sesin o aplicacin) se puede utilizar como una variable en una expresin EL. Por ejemplo, si tenemos un bean con una propiedad firstName en el mbito de la solicitud bajo el nombre customer, esta expresin EL representa el valor de la propiedad firstName del bean.

${customer.firstName}

Pero no se para aqu. EL tambin hace que la informacin de la solicitud y la informacin general del contenedor est disponible como un conjunto de variables implcitas:

Variable Descripcin
param Una collection de todos de los parmetros de la solicitud como un slo valor string para cada parmetro.
paramValues Una collection de todos los valores de los parmetros de la solicitud como un array de valores string por cada parmetro.
header Una collection de todas las cabeceras de solicitud como un slo valor string por cada cabecera.
headerValues Una collection de todos los valores de cabecera de la solicitud como un array de valores string por cada cabecera.
cookie Una collection con todas las cookies de la solicitud en un slo ejemplar de javax.servlet.http.Cookie por cada cokkie.
initParams Una collection de todos los parmetros de inicializacin de la aplicacin en un slo valor string por cada parmetro.
pageContext Un ejemplar de la clase javax.servlet.jspPageContext.
pageScope Una collection de todos los objetos en el mbito de la pgina.
requestScope Una collection de todos los objetos en el mbito de la solicitud.
sessionScope Una collection de todos los objetos en el mbito de la sesin.
applicationScope Una collection de todos los objetos en el mbito de la aplicacin.

Las cinco primeras variables implcitas de la tabla nos ofrecen acceso a los valores de parmetros, cabeceras y cookies de la solicitud actual. Aqu hay un ejemplo de cmo acceder a un parmetro de solicitud llamado listType y a la cabecera User-Agent:


${param.listType}
${header['User-Agent']}

Observa como debemos usar la sintaxis de array para la cabecera, porque el nombre incluye un guin; con la sintaxis de propiedad, sera interpretado como la expresin vairable header.User menos el valor de una variable llamada Agent.

La variable initParameter proporciona acceso a los parmetros de inicializacin que se definen en el fichero web.xml de la aplicacin. La variable pageContext tiene varias propiedades que proporcionan acceso al objeto servlet que representa la solicitud, la respuesta, la sesin y la aplicacin, etc.

Las cuatro ltimas variables son colecciones que contienen todos los objetos de cada mbito especfico. Podemos usarlas para limitar la bsqueda de un objeto en slo un mbito en lugar de buscar en todos ellos, lo que est por defecto si no se especifica ningn mbito. En otras palabras, si hay un objeto llamado customer en el mbito de sesin, estas dos primeras expresiones encuentran el mismo objeto, pero la tercera vuelve vaca:


${customer}
${sessionScope.customer}
${requestScope.customer}

Todas las acciones JSTL aceptan expresiones EL como valores de atributo, para todos los atributos excepto para var y scope, porque estos valores de atributo podran usarse para chequear el tipo en el momento de la traduccin en una futura versin. Hay un atributo de una accin JSTL adicional que no toma un valor de expresin EL, pero slo se usa en la librera XML, por eso lo ignoraremos por ahora. Se pueden usan una o ms expresiones EL en el mismo valor de atributo, y el texto fijo y las expresiones EL se pueden mezclar en el mismo valor de atributo:


First name: &lt;c:out value="${customer.firstName}" /&gt;
&lt;c:out value="First name: ${customer.firstName}" /&gt;

Antes de saltar a ver ejemplos de utilizacin de las acciones Core, dejme cualificar algo que dijimos anteriormente: todas las acciones JSTL de la librera EL aceptan expresiones EL. Realmente hay un conjunto parelelo de libreras JSTL, llamado conjunto de librera RT. que slo acepta expresiones Java del viejo estilo:

First name: <c_rt:out value="<%= customer.getFirstName() %>" /> 

.Procesamiento Condicional y Bucles

Veamos algunos ejemplos de cmo podemos usar el JSTL condicional y las acciones de iteraccin: <c:if>; <c:choose>, <c:when>, y un triple <c:otherwise>; y <c:forEach>. Por el camino, tambin usaremos acciones de salida bsica y de seleccin de variables: <c:out> y <c:set>.

<c:if> nos permite incluir, o procesar, condicionalmente una parte de una pgina, dependiendo de la informacin durante la ejecucin. Este ejemplo incluye un saludo personal si el usuario es un visitante repetitivo, segn lo indica la presencia de una cokkie con el nombre del usuario:

<c:if test="${!empty cookie.userName}">
    Welcome back <c:out value="${cookie.userName.value}" />
</c:if> 

El valor del atributo test es una expresin EL que chequea si la cookie existe. El operador empty combinado con el operador "not" (!) significa que evala a true si el cookie no existe, haciendo que el cuerpo del elemento sea procesado. Dentro del cuerpo, la accin <c:out> aade el valor de la cookie a la respuesta. As de sencillo.

Pasar a travs de una coleccin de datos es casi tan sencillo. Este fragmento itera sobre una coleccin de filas de una base de datos con informacin del tiempo de diferentes ciudades:

<c:forEach items="${forecasts.rows}" var="${city}">
   City: <c:out value="${city.name}" />
   Tomorrow's high: <c:out value="${city.high}" />
   Tomorrow's low: <c:out value="${city.low}" />
</c:forEach>

La expresin EL para el valor items obtiene el valor de la propiedad rows desde un objeto representado por la variable forecasts. Como aprenderemos ms adelante, la acciones de bases de datos de JSTL representan un resultado de consulta como un ejemplar de una clase llamada javax.servlet.jsp.jstl.sql.Result. Esta clase se puede utilizar como un bean con varias propiedades. La propiedad rows contiene un array de ejemplares java.util.SortedMap, donde cada uno representa una fila con valores de columnas. La accin <c:forEach> procesa su cuerpo una vez por cada elemento de la coleccin especificado por el atributo items. Adems de con arrays, la accin funciona con cualquier otro tipo de dato que represente una coleccin, como ejemplares de las clases java.util.Collection o java.util.Map.

Si se especifica el atributo var, el elemento actual de la coleccin se hace disponible para las acciones del cuerpo como una variable con el nombre especificado. Aqu se llamaba city y, como la coleccin es un array de maps, esta variable contiene un nuevo map con valores de columnas cada vez que se procesa el cuerpo. Los valores de las columnas se aaden a la respuesta por el mismo tipo de acciones <c:out> que hemos visto en ejemplos anteriores.

Para ilustrar el uso del resto de las acciones condicionales, extendamos el ejemplo de iteraccin para procesar slo un conjunto fijo de filas por cada pgina solicitada, aadamos enlaces "Previous" y "Next" a la misma pgina. El usuario puede entonces pasar sobre los resultados de la base de datos, mirando unas pocas fila cada vez, asumiendo que el objeto Result se ha grabado en el mbito de la sesin. Aqu est cmo procesar slo algunas filas:

<c:set var="noOfRows" value="10" />

<c:forEach items="${forecasts.rows}" var="${city}"
    begin="${param.first}" end="${param.first + noOfRows - 1}">
    City: <c:out value="${city.name}" />
    Tomorrow's high: <c:out value="${city.high}" />
    Tomorrow's low: <c:out value="${city.low}" />
 </c:forEach>

La accin <c:set> selecciona una variable con el valor especificado por el atributo value; que puede ser un valor esttico, como en este ejemplo, o una expresin EL. Tambin podemos especificar el mbito de la variable con el atributo scope (page, request, session o application). En este ejemplo, hemos seleccionado una variable llamada noOfRows a 10 en el mbito de la pgina (por defecto). Este es el nmero de filas que mostraremos en cada solicitud.

El <c:forEach> en este ejemplo toma los mismos valores para los atributos items y var como antes, pero hemos aadido dos nuevos atributos:

  • El atributo begin toma el ndice (base 0) del primer elemento de la coleccin a procesar. Aqu se selecciona al valor de un parmetro de solicitud llamado first. Para la primera solicitud, este parmetro no est disponible, por eso la expresin se evala a 0; en otras palabtas, la primea fila.
  • El atributo end especifica el ndice del ltimo elemento de la coleccin a procesar. Aqu lo hemos seleccionado al valor del parmetro first ms noOfRows menos uno. Para la primera solicitud, cuando no existe el parmetro de la solicitud, este resultado es 9, por eso la accin itera sobre los ndices del 0 al 9.

Luego aadimos los enlaces "Previous" y "Next":

<c:choose>
  <c:when test="${param.first > 0}">
     <a href="foreach.jsp?first=<c:out value="${param.first - noOfRows}"/>">
                Previous Page</a>
  </c:when>
  <c:otherwise>
     Previous Page
  </c:otherwise>
</c:choose>
<c:choose>
  <c:when test="${param.first + noOfRows < forecasts.rowsCount}">
     <a href="foreach.jsp?first=<c:out value="${param.first + noOfRows}"/>">
                Next Page</a>
  </c:when>
  <c:otherwise>
     Next Page
  </c:otherwise>
</c:choose>

El <c:choose> agrupa una o ms acciones <c:when>, cada una especificando una condicin booleana diferente. La accin <c:choose> chequea cada condicin en orden y slo permite la primera accin <c:choose> con una condicin que se evale a true para procesar su cuerpo. El cuerpo <c:choose> tambin podra contener un <c:otherwise>. Su cuerpo slo se procesa si ninguna de las condiciones de los <c:when> es true.

En este ejemplo, la primera accin <c:when> comprueba si el parmetro first es mayor que cero, es decir, si la pgina muestra un subconjunto de filas distinto del primero. Si esto es cierto, el cuerpo de la accin <c:when> aade un enlace a la misma pgina con un parmetro first seleccionado al ndice del subconjunto anterior. Si no es true, se procesa el cuerpo de la accin <c:otherwise>, aadiendo slo el texto "Previous Page". El segundo bloque <c:choose> proporciona lgica similar para aadir el enlace "Next Page".

.Procesar URLs

Los ejemplos anteriores funcionan bien mientras se utilicen las cookies para seguimiento de sesin. No est todo dado; el navegador podra tener desactivadas las cookies, o no soportarlas. Por lo tanto es una buena idea activar el contenedor para usar la reescritura de URL como backup de los cookies. La reescritura de URL, como podras conocer, significa poner el ID de la sesin en todas las URLs usadas en los enlaces y formularios de la pgina. Una URL reescrita se parece a algo como esto:

myPage.jsp;jspsessionid=ah3bf5e317xmw5

Cuando el usuario pulsa en una lnea como esta, el identificador de sesin ID se enva al contenedor como parte de la URL. La librera corazn de JSTL incluye la accin <c:url>, que tiene cuidado de la reescritura de URL por nosotros. Aqu est como podemos usarla para mejorar la generacin del enlace "Previous Page" del ejemplo anterior:

<c:url var="previous" value="foreach.jsp">
  <c:param name="first" value="${param.first - noOfRows}" />
</c:url>
<a href="<c:out value="${previous}"/>">Previous Page</a>

<c:url> soporta un atributo var, usado para especificar una variable para contener la URL codificada, y un atributo value para contener la URL a codificar. Se pueden especificar parmetros string para solicitar la URL usando acciones <c:param>. Los caracteres especiales en los parmetros especificados por elementos anidados son codificados (si es necesario) y luego aadidos a la URL como parmetros string de la consulta. El resultado final se pasa a travs del proceso de reescritura de URL, aadiendo un ID de sesin si est desactivado el seguimiento de sesin usando cookies. En este ejemplo, se utiliza la URL codificada como un valor de atributo href en un elemento de enlace HTML.

<c:url> tambin realiza otro buen servicio. Como podra preocuparte, las URLs relativas en elementos HTML tambin deben ser relativas a la pgina que los contiene o al directorio raz del servidor (si empiezan con una barra inclinada). La primera parte del path de una URL de una pgina JSP se llama path de contexto, y podra variar de instalacin a instalacin. Por lo tanto deberamos evitar codificar el path de contexto en las pginas JSP. Pero algunas veces realmente querremos utilizar un path de URL relativo al servidor en elemento HTML; por ejemplo cuando necesitamos referirnos a un fichero de imagen localizado en el directorio /images compartido por todas las pginas JSP. Las buenas noticias es que si especificamos una URL con un barra inclinada como el valor <c:url>, lo convierte en un path relativo al servidor. Por ejemplo, en una aplicacin con el path de contexto /myApp, la accin <c:url> convierte el path a /myApp/images/logo.gif:

<c:url value="/images/logo.gif" />

Hay unas cuantas acciones ms relacionadas con las URLs en la librera corazn. La accin <c:import> es una accin ms flexible que la accin estndar <jsp:include>. Podemos usarla para incluir contenido desde los recursos dentro de la misma aplicacin Web, desde otras aplicaciones Web en el mismo contenedor, o desde otros servidores, usando protocolos como HTTP y FTP. La accion <c:redirect> nos permite redirigir a otro recurso en la misma aplicacin Web, en otra aplicacin Web o en un servidor diferente. Ambas acciones son fciles de usar, por eso te dejamos como ejercicio que las prctiques.

COMPARTE ESTE ARTÍCULO

ENVIAR A UN AMIGO
COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN GOOGLE +
ARTÍCULO ANTERIOR

SIGUIENTE ARTÍCULO

¡SÉ EL PRIMERO EN COMENTAR!
Conéctate o Regístrate para dejar tu comentario.