Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Table of Contents
Introducción ......................................................................................................... 1
Introducción ................................................................................................. 1
¿Que es JSTL? ............................................................................................. 3
JSTL es fácil ................................................................................................ 4
Historia de JSTL ........................................................................................... 4
Instalar JSTL ................................................................................................ 4
Expression Language (EL) ...................................................................................... 8
EL .............................................................................................................. 8
Operadores .................................................................................................10
Literales .....................................................................................................11
Objetos implícitos ........................................................................................12
Funciones EL ..............................................................................................15
Etiquetas ............................................................................................................19
Core ..........................................................................................................19
Bases de datos .............................................................................................28
I18n y formateo ...........................................................................................34
XML .........................................................................................................44
Validadores de bibliotecas (TLVs) ..........................................................................50
¿Que es un TLV? .........................................................................................50
TLVs de JSTL .............................................................................................51
Repaso a XPath ...................................................................................................52
¿Que es XPath? ...........................................................................................52
Selección ....................................................................................................52
Expresiones XPath .......................................................................................55
Métodos .....................................................................................................55
Introducción
Introducción
JSP
¿Que es JSP?
1
JSTL
• JSP es una tecnología Java para escribir programas que se ejecutan en el servidor.
• Una página JSP es HTML convencional al que se le añaden instrucciones JSP ejecutables.
• Las instrucciones JSP están formadas por etiquetas similares a las del código HTML.
y su resultado
Figure 1.
¿Como se ejecuta?
• Si el usuario pide una página con extensión .jsp el servidor ejecuta el JSP y añade el resultado
al HTML original de la página.
• Para ejecutar una página JSP, el servidor realiza internamente varias operaciones:
• JSP permite crear páginas dinámicas (o sea, páginas cuyo contenido varia en cada ejecución).
2
JSTL
• Con JSP podemos responder a peticiones o información que el usuario nos envía.
• Con JSP podemos acceder a bases de datos o realizar cualquier operación posible con Java.
• JSP puede incluir instrucciones JSP y/o código en Java pero este último no es aconsejable
porque produce páginas complicadas de mantener.
JSTL
¿Que es JSTL?
• JSTL significa Java Standard Template Library (biblioteca de etiquetas estándar para Java).
• JSTL es sencillo.
¿Qué requiere?
¿Que es JSTL?
JSTL es una biblioteca que implementa funciones de uso frecuente en aplicaciones JSP. En con-
creto, JSTL proporciona
• Procesamiento de XML.
• Un lenguaje de expresión para referenciar objetos y sus propiedades sin necesidad de código
Java.
3
JSTL
JSTL es fácil
Por su simplicidad, JSTL solo requiere conocimientos rudimentarios de Java, JSP, y aplicaciones
Web. Cualquier desarrollador puede comenzar a usarlo de forma casi inmediata.
Historia de JSTL
Con JSTL se pretendía recopilar las etiquetas JSP más usadas en una biblioteca estándar que pudiera
usarse en todos los contenedores JSP
Las iniciativas para crear un estándar dentro del proceso JCP se conocen como JSR (Java Specifica-
cion Request, Petición de Especificación Java). La JSR nº 52 [http://www.jcp.org/jsr/detail/52.jsp]
se llamó "A Standard Tag Library for JavaServer Pages", o abreviadamente JSTL. Fue solicitada
originalmente por Eduardo Pelegri-Llopart y Anil Vijendran, empleados de SUN. En su desarrollo
participaron individuos como Jason [http://today.java.net/cs/user/print/au/8?x-t=full.view]Hunter
[http://www.javahispano.org/text.viewer.action?file=jason_hun_es], y representantes de varias or-
ganizaciones (ASF, Adobe, BEA, y otras).
La especificación JSTL 1.0 fue terminada el 11 de julio de 2002. Unos días después apareció la
primera implementación [http://jakarta.apache.org/taglibs/doc/standard-1.0-doc/intro.html ] creada
por miembros del proyecto Taglibs [http://jakarta.apache.org/taglibs/doc/standard-doc/intro.html] de
la fundación Apache. La última versión de JSTL a día de hoy (mayo de 2004) es la 1.1, imple-
mentada por el proyecto Taglibs.
Instalar JSTL
Descargar el software
Para trabajar con JSTL necesitamos
4
JSTL
Instalar Tomcat
Para instalar Tomcat
Cada directorio tiene un propósito, pero por ahora solo necesitamos saber que en bin están los
scripts de arranque del servidor, y en webapps las aplicaciones Web.
$CATALINA_HOME/webapps/miAplicacion
####WEB-INF
####classes
####lib
commons-logging-1.0.3.jar
jstl-1.0.2.jar
standard-1.0.4.jar
En cualquier caso, no esta de más añadir un web.xml. Se coloca bajo el directorio WEB-INF:
5
JSTL
<description>JSTL test</description>
<display-name>JSTL test</display-name>
</web-app>
En toda página JSP hay que declarar la biblioteca a la que pertenece cada etiqueta que usemos.
Puesto que son varias líneas, lo más comodo es hacer las declaraciones en un fichero aparte, y luego
incluir dicho fichero en nuestras páginas JSP. Este sistema evita repetir el mismo texto en todas las
páginas, y si en el futuro añadimos más bibliotecas, solo tendremos que modificar un único fichero.
En este ejemplo hemos usado la etiqueta c:out de la librería core para mostrar un mensaje.
Herramientas como Ant o Maven, nos permiten automatizar la construcción y despliegue de una
aplicación a partir de su código fuente. Normalmente comenzamos un proyecto escribiendo un
script, pero si somos usuarios de Maven podemos generar automáticamente una aplicación de ejem-
plo que tomaremos como punto de partida.
Warning
Maven es una herramienta similar a Ant pero más flexible y compleja. Si eres principiante
probablemente te traiga más complicaciones que beneficios.
Maven permite generar proyectos de ejemplo (script incluido) para varias tecnologías usando el plu-
gin genapp [http://maven.apache.org/reference/plugins/genapp/goals.html]. Por ahora existen plan-
tillas para JSTL, Struts, Struts+JSTL, EJB, y otros. A continuación se explica como.
6
JSTL
$ maven genapp
__ __
| \/ |__ _Apache__ ___
| |\/| / _` \ V / -_) ' \ ~ intelligent projects ~
7
JSTL
El proyecto resultante incluye las dependencias para usar Cactus, HttpUnit, y JUnit (de ahí que tarde
tanto en descargarse).
• Las expresiones JSTL comienzan con ${ y terminan con }. Lo que hay en medio es tratado
como una expresión.
• Literales. Son números, cadenas delimitadas por comillas simples o dobles, y los valores
8
JSTL
• Podemos usar expresiones en cualquier parte del documento, o como valores de los atributos de
etiquetas JSTL, exceptuando los atributos var y scope, que no aceptan expresiones.
• En cualquier sitio donde sea valido colocar una expresión, también será válido colocar más de
una. Por ejemplo: value="Hola ${nombre} ${apellidos}".
• Para acceder al campo de un bean java, o a un elemento de una colección (array, o Map), se usa
el operador punto, o el operador corchete:
${bean.propiedad}
${map.elemento}
${header['User-Agent']}
Si un campo de un bean es otro bean, podemos encadenar puntos para acceder a una propiedad
del segundo bean:
${bean1.bean2.propiedad}
• Las expresiones pueden aparecer como parte del valor de un atributo de una etiqueta:
<c:out value="${2+2}"/>
<c:out value="${nombre}"/>
<c:if test="${tabla.indice % 2 == 0}">es par</c:if>
EL es opcional en JSTL 1.0. Es por ello que cada una de las cuatro bibliotecas de JSTL tiene dos
versiones: [PENDIENTE]
• Versión EL: usa expresiones EL. Sus directivas taglib correspondientes son
• Versión RT: usa expresiones del entorno de ejecución de JSP. Sus directivas taglib correspondi-
entes son
9
JSTL
Operadores
Los operadores y sus significados son los mismos que en otros lenguajes de programación.
Acceso a datos
El operador punto (.) permite recuperar la propiedad de un objeto por su nombre. Ejemplo:
${libro.paginas}
Las propiedades se recuperan usando las convenciones de los JavaBeans. Por ejemplo, en el código
anterior, invocábamos el método libro.getPaginas() del objeto libro.
El operador corchete ([]) permite recuperar una propiedad con nombre o indexada por número.
Ejemplo:
${libro["paginas"]}
${libro[0]}
${header['User-Agent']}
Dentro del corchete puede haber una cadena literal, una variable, o una expresión.
10
JSTL
Operadores aritméticos
Table 3.
Operador Descripción
+ suma
- resta
* multiplicación
/ div división
% mod resto
Operadores lógicos
Table 4.
Operador Descripción
&& and true si ambos lados son ciertos
|| or true si alguno de los lados son ciertos
! not true si la expresión es falsa
Operadores relacionales
Table 5.
Operador Descripción Ejemplo Resultado
== eq comprobación de ${5 == 5} true
igualdad
!= ne comprobación de ${5 != 5} false
desigualdad
< lt menor que ${5 < 7} true
> gt mayor que ${5 > 7} false
<= le menor o igual que ${5 le 5} true
>= ge mayor o igual que ${5 ge 6} false
Operador empty
El operador empty comprueba si una colección o cadena es vacía o nula. Ejemplo: ${empty
param.login}
Literales
En expresiones EL podemos usar números, caracteres, booleanos (palabras clave true, false), y
nulls (palabra clave null).
11
JSTL
Objetos implícitos
Ciertos objetos son automáticamente accesibles a cualquier etiqueta JSP.
A través de ellos es posible a cualquier variable de los ámbitos page, request, session, ap-
plication, a parametros HTTP, cookies, valores de cabeceras, contexto de la página, y
parámetros de inicialización del contexto. Todos, excepto pageContext, están implementados
usando la clase java.util.Map.
Ejemplo:
El resultado es
accept-encoding=gzip, deflate
cache-control=no-cache
connection=Keep-Alive
referer=http://127.0.0.1:8080/sampleJSTL/
host=127.0.0.1:8080
accept-language=es
user-agent=Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; MyIE2; .NET CLR 1.
cookie=JSESSIONID=E58368E8FFA066A654750C4CED08AA88
accept=*/*
12
JSTL
Host: 127.0.0.1:8080
Host: 127.0.0.1:8080
Accept-Language: es
pageContext
Aquí se listan algunos de los valores disponibles en el contexto de la página. Existen otros que po-
demos consultar en el javadoc. Por ejemplo, pageContext.request.authType esta
ejecutando el método HttpServletRequest.getAuthType()
[http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/http/HttpServletRequest.html#getAuthType()].
De igual modo podemos acceder al resto de métodos.
Table 7. pageContext
Expresión Descripción Ejemplo
${pageContext.excepti Devuelve una descripción del "Algo ha ido mal"
on.message} error cuando la página en curso
es una página de error JSP.
${pageContext.errorDa Información de un error JSP.
ta}
${pageContext.request Tipo de autentificación usado BASIC
.authType} en la página.
${pageContext.request Identificador del usuario fulano
.remoteUser} (cuando esta en uso la
autentificación del contenedor).
${pageContext.request Nombre (también llamado con- /apuntes-jstl
.contextPath} texto) de la aplicación.
${pageContext.request Array de cookies.
.cookies}
${pageContext.request Método HTTP usado para ac- GET
.method} ceder a la página.
${pageContext.request Query de la página (el texto de p1=valor&p2=valor
.queryString} la URL que viene despues del
PATH)
${pageContext.request URL usada para acceder a la ht-
.requestURL} página. tp://localhost/app/pa
gecontext.jsp
${pageContext.session Contiene true si la sesión es true
.new} nueva, false si no lo es.
${pageContext.servlet Información sobre el contene- Tomcat 5.0.1
Context.serverInfo} dor JSP.
13
JSTL
authType:
remoteUser:
contextPath: /sampleJSTL
cookies: [Ljavax.servlet.http.Cookie;@1add463
method: GET
queryString:
requestURL: http://127.0.0.1:8080/sampleJSTL/pageContext.jsp
session.new: false
serverInfo: Apache Tomcat/4.1.29
message:
• message porque no es una página de error, y por tanto no existe una excepción en el contexto
de página.
pageContext.errorData
En JSP 2.0, cuando se produce un error la excepción ocurrida está disponible en el ámbito re-
quest con el nombre javax.servlet.error.exception. Ademas, se adjunta al contexto
de la página, información adicional en forma de bean con nombre errorData. Este bean tiene las
siguientes propiedades:
Table 8.
Propiedad Tipo Java Descripción
requestURI String URI de la petición fallida.
servletName String Nombre de la página o servlet
que lanzó la excepción.
statusCode int Código HTTP del fallo.
throwable Throwable La excepción que produjo el
fallo.
Para declarar una página de error JSP que responda a un código o excepción, podemos usar el
web.xml:
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/error.jsp</location>
</error-page>
<error-page>
<exception-code>500</exception-code>
<location>/error.jsp</location>
</error-page>
14
JSTL
Para probarla podemos emplear esta otra página que lanza intencionadamente una excepción:
Funciones EL
Las funciones representan un modo de extender la funcionalidad del lenguaje de expresiones. Se
usan dentro de cualquier expresión EL, ejemplo:
<function>
<description>
Returns the number of items in a collection
or the number of characters in a string.
</description>
<name>length</name>
<function-class>
org.apache.taglibs.standard.functions.Functions
</function-class>
<function-signature>
int length(java.lang.Object)
</function-signature>
</function>
15
JSTL
Todas las funciones EL interpretan las variables no definidas o definidas con valor igual a null,
como cadenas vacías.
fn:contains
Devuelve true si una cadena contiene a otra, false en caso contrario.
Ejemplo:
fn:containsIgnoreCase
Devuelve true si una cadena contiene a otra sin distinguir entre minúsculas/mayúsculas, false
en caso contrario.
Ejemplo:
fn:endsWith
Devuelve true si una cadena termina con el sufijo indicado, false en caso contrario.
Ejemplo:
16
JSTL
fn:escapeXml
Codifica los caracteres que podrían ser interpretados como parte de las etiquetas XML.
fn:escapeXml(string) # String
fn:indexOf
Devuelve el índice (empezando desde cero) dentro de una cadena donde comienza otra cadena espe-
cificada.
fn:join
Convierte en cadena los elementos de un array. El separador se usa para separar los elementos en la
cadena resultante.
fn:length
Devuelve el número de caracteres en una cadena, o de elementos en una colección.
fn:length(input) # integer
fn:replace
Recorre una cadena (inputString) reemplazando todas las ocurrencias de una cadena (be-
foreSubstring) por otra (afterSubstring).
fn:split
Divide una cadena en subcadenas, usando como separador cualquier carácter de otra cadena. Los ca-
racteres de la segunda cadena no forman parte del resultado.
17
JSTL
fn:startsWith
Comprueba si una cadena comienza por otra.
fn:substring
Devuelve un subconjunto de una cadena. Los índices comienzan en cero. La cadena resultante comi-
enza en beginIndex y llega hasta el caracter en endIndex-1 (incluido). La longitud de la ca-
dena es endIndex-beginIndex.
• Si endIndex es menor que cero o mayor que la longitud de la cadena, se ajusta su valor a la
longitud de la cadena.
fn:substringAfter
Devuelve la porción de una cadena que viene a continuación de cierta subcadena. La cadena
devuelta comienza en el siguiente caracter tras la subcadena buscada.
fn:substringBefore
Devuelve la porción de una cadena que viene antes de cierta subcadena. La cadena devuelta va
desde el primer carácter hasta el carácter anterior a la subcadena buscada.
fn:toLowerCase
Convierte todos los caracteres a minúsculas.
fn:toLowerCase(string) # String
18
JSTL
fn:toUpperCase
Convierte todos los caracteres a mayúsculas.
fn:toUpperCase(string) # String
fn:trim
Elimina el espacio en blanco en los extremos de una cadena.
fn:trim(string) # String
Etiquetas
Core
Etiquetas para iteración sobre datos, operaciones condicionales, e importación de datos de otras
páginas
c:out
Muestra el resultado de una expresión. Su funcionalidad es equivalente a la de <%= %>.
Table 9.
Atributo Descripción Requerido Por defecto
value información a mostrar sí ninguno
default información a mostrar no cuerpo
por defecto
escapeXml true si debe convertir no true
caracteres especiales a
sus correspondientes
entidades (por ejemplo,
> para <).
Ejemplos:
Para evitar que un nombre sea confundido con una expresión lo ponemos entre comillas:
Hemos usado comillas simples en User-Agent para que no se confundan con las comillas dobles
que delimitan el valor del atributo, también podríamos haber usado \"User-Agent\":
Ejemplo de creación dinámica de un documento XSL: [PENDIENTE: demasiado complejo para es-
19
JSTL
tar aqui?]
c:set
Table 10.
Atributo Descripción Requerido Por defecto
value Información a grabar. no cuerpo
target Nombre de la variable no ninguno
cuya propiedad será
modificada
property Propiedad a modificar no ninguna
var Nombre de la variable no ninguno
en la que guardar.
scope Ámbito de la variable no page
en la que grabar la
información (page,
request, session,
o application)
Ejemplos:
Si colocamos el valor en el cuerpo de la etiqueta, se suprimen los espacios del comienzo y final del
cuerpo.
c:remove
Table 11.
Atributo Descripción Requerido Por defecto
var Nombre de la variable a sí --
quitar.
20
JSTL
Cuando no se especifica ámbito, la etiqueta busca en todos los ámbitos por turno, yendo del más es-
pecifico al más general (page, request, session, application), hasta encontrar una vari-
able con ese nombre. Si la variable no se encuentra, la etiqueta termina sin error.
c:if
Table 12.
Atributo Descripción Requerido Por defecto
test Condición a evaluar. sí --
Solo procesa el cuerpo
si es true.
var Nombre del atributo no ninguno
con el que grabar el res-
ultado booleano de la
condición.
scope Ámbito en el que expo- no page
ner el atributo anterior.
En el cuerpo es posible colocar otras etiquetas, incluyendo otras <c:if>. Es útil guardar el res-
ultado de evaluar la condición para evitar repetir los cálculos.
Ejemplos:
Table 13.
Atributo Descripción Requerido Por defecto
test Condición a evaluar sí --
21
JSTL
Ejecuta el cuerpo de la primera etiqueta when cuya condición evalúe a true, o el cuerpo de la
etiqueta otherwise (si existe).
Ejemplos:
<c:choose>
<c:when test="${hour>=7 && hour<=12}"> morning </c:when>
<c:when test="${hour>12 && hour<=17}"> afternoon </c:when>
<c:when test="${hour>17 && hour<22}"> evening </c:when>
<c:otherwise>night</c:otherwise>
</c:choose>
c:forEach
Permite iterar sobre los elementos siguientes:
Table 14.
Atributo Descripción Requerido Por defecto
items Colección sobre la que no ninguno
iterar.
begin Elemento con el que no 0
empezar (0=primero).
end Elemento con el que no último
terminar (0=primero).
step Procesa solo cada step no 1 (todos)
elementos.
var Nombre del atributo no ninguno
con el que exponer el
elemento actual.
varStatus Nombre de la variable no ninguno
con la que exponer el
estado de la iteración.
22
JSTL
Ejemplos:
c:forTokens
Permite descomponer una cadena en tokens.
Analizar una cadena se llama parsing. Las partes en las que se descompone una cadena se llaman
tokens.
Table 16.
Atributo Descripción Requerido Por defecto
items Cadena sobre la que it- sí ninguno
erar
delims Caracteres delimita- sí ninguno
dores
var Nombre del atributo no ninguno
con el que exponer el
token actual
Los delimitadores que aparecen uno tras otro son tratados como si solo existiera uno.
Ejemplos:
<ul>
<c:forTokens items="Tinky Winki,Dipsy,Laa-Laa,Po" delims="," var="teletubbie">
<li><c:out value="${teletubbie}"/></li>
</c:forTokens>
</ul>
La salida de lo anterior es
23
JSTL
<ul>
<li>Tinky Winki</li>
<li>Dipsy</li>
<li>Laa-Laa</li>
<li>Po</li>
</ul>
<c:forTokens items="${applicationScope['org.apache.catalina.jsp_classpath']}"
delims=";"
var="item">
<c:out value="${item}"/><br/>
</c:forTokens>
c:import, c:param
c:import
c:import proporciona toda la funcionalidad de jsp:include y añade otras:
Table 17.
Atributo Descripción Requerido Por defecto
url URL para importar la sí --
página. Es válido cu-
alquier protocolo so-
portado por
java.net.URL. Es
decir, al menos HTTP,
HTTPS, FTP, file, y
JAR.
context Barra (/) seguido del no contexto actual
nombre de la aplicación
local
var Nombre del atributo no muestra en página
con el que exponer el
texto importado.
scope Ámbito del atributo an- no page
terior.
charEncoding Juego de caracteres con no ISO-8859-1
el que importar los da-
tos.
varReader Nombre de una variable no ninguno
con la que exponer el
24
JSTL
En HTML, la URL relativa /images/smiley.jpg lee un fichero de la raiz del servidor web,
pero en JSTL, esa misma URL lee el fichero de la raíz de nuestra aplicación web. Si quisieramos
que la URL fuera relativa a otra aplicación Web usariamos
Cuando dos páginas están en la misma aplicación web, comparten el mismo ámbito request,
session, y application. Si las páginas estan en diferente aplicación y son accedidas mediante
c:import, ambas comparten el ámbito request.
c:param
c:import puede tener hijos c:param, que se usan para pasar parametros a la URL a recuperar.
Los atributos de c:param son
Table 18.
Atributo Descripción Requerido Por defecto
name nombre del parametro sí --
value valor del parametro no cuerpo
Si quieres que un bean sea accesible en otra página, seria engorroso convertirlo en una cadena de
texto, es mejor usar c:set para guardar esta información.
Ejemplos
Cuando queremos reutilizar un texto lo grabamos en una variable:
Podemos hacer que los contenidos leídos sirvan de entrada a otra etiqueta colocando c:import en
el cuerpo de dicha etiqueta (suponiendo que esta última lo admita):
<string:lowerCase>
<c:import url="pagina.jsp"/>
</string:lowerCase>
<c:import url="http://www.universalmusic.fi/tiktak/index.php">
<c:param name="id" value="tuotanto"/>
</c:import>
Página pagina1.jsp:
25
JSTL
</c:import>
El tiempo meteorológico fue importado de la página weather.jsp.
</body>
</html>
Página weather.jsp:
c:redirect
Ejecuta un forward. Es decir, se para la ejecución de la página actual (no se ejecuta nada de lo que
este por debajo de esta instrucción) y el navegador es enviado a otra URL.
Table 19.
Atributo Descripción Requerido Por defecto
url URL a la que redirigir. sí --
context Barra (/) seguido del no contexto actual
nombre de una
aplicación local.
Ejemplos:
<c:redirect url="weatherPopUp.jsp"/>
<c:param name="city" value="Madrid"/>
</c:redirect>
c:url
Sirve para mostrar una URL o para grabarla en una variable. Sus atributos son:
Table 20.
Atributo Descripción Requerido Por defecto
value Base URL a mostrar o sí --
almacenar.
context Barra (/) seguido del no contexto actual
nombre de una
aplicación local.
var Nombre del atributo en no ningúno
el que exponer la URL.
scope Ámbito del atributo an- no page
terior.
26
JSTL
Ejemplos:
c:catch
Normalmente los errores en una página JSP interrumpen la ejecución de la página y se envían al
contenedor, que a su vez muestra un mensaje de error. La etiqueta c:catch permite capturar y
tratar los errores.
Table 21.
Atributo Descripción Requerido Por defecto
var Variable para exponer no ninguno
información sobre el er-
ror.
Si hay un error en alguna sentencia del cuerpo de la etiqueta se interrumpe la ejecución y se con-
tinua después del catch.
Para que una página redirija a otra en caso de fallar su procesamiento basta con colocar esta dir-
ectiva en ella:
Luego tendremos que crear la página de error, que deberá comenzar con esta línea:
27
JSTL
El error fue..<br/>
<c:out value="${pageContext.exception.message}"/>
</body>
</html>
Bases de datos
Warning
Una aplicación es más mantenible si separa las capas de presentación, lógica, y acceso a
datos. Acceder a datos desde el JSP solo es recomendable para prototipos.
sql:DataSource
Table 22.
Atributo Descripción Requerido Por defecto
dataSource Base de datos a usar. no ningúno
driver Nombre de la clase JD- no ningúno
BC a usar como driver.
url URL de la base de da- no ningúno
tos.
user Nombre del usuario de no ningúno
la base de datos.
password Password del usuario no ningúno
de la base de datos.
var Nombre de la variable no ningúno
que representa la base
de datos.
scope Ámbito de la variable no page
anterior.
Si no usamos var o scope, el datasource declarado reemplaza al datasource por defecto. Esta
etiqueta no implementa pooling de conexiones, pero con ella podremos referenciar un dataSource
preexistente que sí lo implemente.
Para usar el driver de un fabricante, obviamente necesitaremos colocar en el classpath dicho driver.
Normalmente descargamos un archivo jar y lo colocamos en el WEB-INF/lib. Como ejemplo,
aqui están el de mysql [http://dev.mysql.com/downloads/connector/j/3.0.html], oracle
[http://otn.oracle.com/software/tech/java/sqlj_jdbc/index.html], y HSQL
[http://hsqldb.sourceforge.net/].
<sql:setDataSource driver="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/test"
user="alicia"
password="secreto"/>
28
JSTL
// MySQL
<sql:setDataSource driver="com.mysql.jdbc.Driver"
url="jdbc:mysql://maquina:puerto/baseDeDatos"
...
// HSQL
<sql:setDataSource driver="org.hsqldb.jdbcDriver"
url="jdbc:hsqldb:."
...
// Puente JDBC-ODBC de SUN con driver de SUN. No recomendado para producción.
// Usa el formato jdbc:odbc:<data-source-name>[;<attribute-name>=<attribute-valu
<sql:setDataSource driver="sun.jdbc.odbc.JdbcOdbcDriver"
url="jdbc:odbc:nombreDsn;UID=uid;PWD=password"
...
<sql:setDataSource driver="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/test"
user="alicia"
password="secreto"
var="development1"/>
<sql:setDataSource dataSource="${development1}"
scope="request" />
sql:query
Se usa para consultar la base de datos.
Table 23.
Atributo Descripción Requerido Por defecto
sql Consulta SQL a no si ponemos el SQL cuerpo
ejecutar. en el cuerpo de la
etiqueta
dataSource Proveedor de conex- no
iones.
startRow Primeras filas a ignorar no 0 (primero)
(ej: 10=ignora las diez
primeras filas).
maxRows Máximo número de no
filas.
var Variable con la que ex- sí ningúno
poner el resultado.
scope Ámbito de la anterior no page
variable.
Esta etiqueta no muestra datos, solo los graba en la variable indicada por var.
El atributo maxRows indica el número por defecto de filas a recuperar. Podemos asignar un valor a
este atributo para cambiar el límite de filas, o asignar -1 si no queremos límite.
29
JSTL
• columnName: Lista de nombres de columnas. Podemos acceder a ella con paréntesis cuadrados
o iterando sobre ella.
• limitedByMaxRows: Booleano que indica si el resultado contenía más de las filas indicadas
por maxRows.
Ejemplo:
<sql:query var="users">
SELECT * FROM USERS
</sql:query>
Podemos usar otras etiquetas para proporcionar una consulta SQL en el cuerpo de la etiqueta.
Supongamos que por algún motivo te interesa mantener todas las consultas en un fichero XML y
quieres recuperar la consulta que devuelve todos los usuarios:
<x:parse var="doc">
<query>
<getAllUsers>
SELECT * FROM users
</getAllUsers>
</query>
<x:parse>
<sql:query var="doc">
<x:out select="$doc/query/getAllUsers"/>
</sql:query>
<sql:query var="savvyUsers">
SELECT name, phone_extension FROM USERS WHERE CLUE > 0
</sql:query>
<ul>
<c:forEach items="${savvyUsers.rows}" var="row">
<li>
<c:out value="${row.name}"/>,
<c:out value="${row[1]}"/>
</li>
</c:forEach>
</ul>
30
JSTL
sql:update
Se usa para modificar la base de datos.
Table 24.
Atributo Descripción Requerido Por defecto
sql consulta SQL a ejecutar no cuerpo
dataSource proveedor de conex- no
iones
var variable para guardar el no ningúno
número de filas actual-
izadas
scope ámbito de la anterior no page
variable
Varios ejemplos:
<sql:update>
INSERT INTO citas
SET cita = "es reinventar el tornillo, digo.. la rueda, bueno, y el tornillo
autor = "Luis"
date = "2004-03-03";
</sql:update>
<sql:update sql="DELETE FROM citas WHERE autor = 'Luis'"/>
<sql:update var="n">
DELETE FROM citas
WHERE autor = 'Luis'
</sql:update>
Hemos borrado <c:out value="${n}"/> filas.
sql:param
Se usa para pasar parámetros a las consultas ajustando la codificación de caracteres de forma segura.
Table 25.
Atributo Descripción Requerido Por defecto
value valor del parámetro no cuerpo
La etiqueta sql:param sustituirá los caracteres ? de las sentencias SQL. Los caracteres ?
únicamente pueden usarse para sustituir un valor (string, número, u otro) en un comando SQL.
Ejemplo:
<sql:update>
31
JSTL
¿Porque es importante?
Al pasar parametros a una consulta es importante ajustar la codificación de caracteres de forma se-
gura para evitar el problema de inyección de código SQL.
Supongamos la típica página de login/password que traslada directamente el valor de los campos del
formulario a la sentencia SQL:
¿Pero que ocurre si en ponemos una comilla simple en el campo usuario? No he encontrado un
ejemplo real en JSP para ilustrar este comportamiento, pero valga esta Web en ASP:
La sentencia es incorrecta, y además el mensaje de error muestra datos sobre las interioridades de la
aplicación. Si volvemos a probar introduciendo esta cadena en el campo usuario
' OR Passwd<>'
Observa que he puesto xxxxx en los campos que no conozco, pero tampoco me importa porque con
gracias al OR, estoy forzando a devolver el contenido completo de la tabla. Probablemente el pro-
grama lea el primer usuario de la lista devuelta y asuma que esa es nuestra identidad, lo que puede
propiciar actos criminales, y multas por no proteger adecuadamente los datos de los usuarios del sis-
tema.
sql:dateParam
Table 26.
Atributo Descripción Requerido Por defecto
value fecha a sustituir en el sí --
carácter ?
type time, date, o timestamp no timestamp
Ejemplo:
<sql:query>
SELECT * FROM USERS
32
JSTL
sql:transaction
Se usa para lanzar actualizaciones y consultas bajo una transacción. Para ello las sentencias
sql:update y sql:query se colocan como cuerpo de esta etiqueta. Todas las sentencias en una
transacción tienen éxito o fallan como unidad, es decir si alguno de ellos falla se realiza un rollback
de todos, y la base de datos queda como antes de comenzar la transacción.
En el cuerpo también podemos poner texto estático, o cualquier etiqueta JSP. Si ocurre algún error
en alguna etiqueta del cuerpo, la transacción realiza un rollback.
Table 27.
Atributo Descripción Requerido Por defecto
dataSource DataSource proveedor no
de conexiones.
isolation Nivel de aislamiento. no
El dataSource de esta etiqueta será usado por todas las etiquetas contenidas en el cuerpo, independi-
entemente de que en ellas se especifique un dataSource diferente. Esto es así porque las transac-
ciones están vinculadas por definición a una única conexión.
Table 28.
nivel dirty read? nonrepeatable reads? phantom reads?
read_uncommitted -- -- --
read_committed evitado -- --
repeatable_read evitado evitado --
serializable evitado evitado evitado
• dirty read es una lectura de filas que aun no han sido confirmadas (commited) por otra
transacción.
• phantom read es como una nonrepeatable read, pero solo ocurre respecto a filas que
han sido añadidas desde la primera lectura, no en filas que hayan sido modificadas.
El modo serializable ofrece la mayor protección pero a mayor protección, menor rendimiento.
Ejemplo:
<%--
Adding New User Accounts to MySQL
http://dev.mysql.com/doc/mysql/en/Adding_users.html
--%>
<sql:setDataSource driver="com.mysql.jdbc.Driver"
33
JSTL
url="jdbc:mysql://localhost:3306/test"
user="alicia"
password="secreto"
var="testDatabase"/>
<sql:transaction dataSource="${testDatabase}">
<sql:update>
GRANT ALL PRIVILEGES ON *.* TO 'monty'@'localhost'
IDENTIFIED BY 'some_pass' WITH GRANT OPTION;
</sql:update>
<sql:update>
GRANT ALL PRIVILEGES ON *.* TO 'monty'@'%'
IDENTIFIED BY 'some_pass' WITH GRANT OPTION;
</sql:update>
</sql:transaction>
I18n y formateo
La internacionalización (i18n) consiste en preparar una aplicación para que funcione en distintos
idiomas (incluyendo formateo de fecha y moneda).
i18n
fmt:bundle
Permite cargar recursos de mensajes específicos solo para una zona de la página. Ver
fmt:message.
Table 29.
Atributo Descripción Requerido Por defecto
basename Nombre del recurso a sí ninguno
usar.
prefix Cadena a usar como no ninguno
prefijo de cada clave.
Ejemplo:
<fmt:bundle basename="ApplicationResources">
<fmt:message key="welcome.user"/>
</fmt:bundle>
fmt:message
Acepta una clave y devuelve el resultado correspondiente a la clave en el fichero de recursos espe-
cificado.
Table 30.
Atributo Descripción Requerido Por defecto
key Clave. no cuerpo
bundle Recurso. no
var Variable en la que no ninguno
guardar el resultado.
scope Ámbito de la variable no page
anterior.
34
JSTL
El recurso consiste en un fichero de texto accesible a través del classpath que contiene pares
nombre=valor como los usados en la clase java.util.Properties. Por ejemplo:
La cadena ${0} es un parametro que podemos pasar a la cadena leída para personalizar el mensaje.
Para ello se usa la etiqueta fmt:param que veremos más adelante. Por ejemplo, suponiendo un ob-
jeto usuario con un campo nombre, podríamos obtener la cadena Hola Jano! (suponiendo que
Jano es el valor del campo nombre) con el siguiente código:
<fmt:message key="welcome.user">
<fmt:param value="${usuario.nombre}"/>
</fmt:message>
• etiqueta fmt:bundle,
El nombre del fichero cargado por esta será nombre_XX.properties, donde XX es el locale
activo. Es decir, si el nombre es ApplicationResources, y el locale activo es en, se intentará
cargar el fichero ApplicationResources_en.properties del classpath, y si no se encuen-
tra, se probará con el nombre por defecto ApplicationResources.properties.
<fmt:setBundle basename="ApplicationResources"/>
<fmt:message key="label.password"/>
<fmt:bundle basename="ApplicationResources">
<fmt:message key="label.password"/>
</fmt:bundle>
<context-param>
<param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
<param-value>ApplicationResources</param-value>
</context-param>
<fmt:message key="label.password"/>
fmt:param
Algunos mensajes aceptan parámetros, de forma parecida a los PreparedStatement de SQL.
Ver fmt:message.
Table 31.
35
JSTL
Ejemplo:
<fmt:message key="welcome.user">
<fmt:param value="${usuario.nombre}"/>
</fmt:message>
fmt:setBundle
Permite cargar recursos de mensajes específicos. Ver fmt:message.
Table 32.
Atributo Descripción Requerido Por defecto
basename Nombre del recurso a sí ninguno
usar.
var Variable en la que gra- no ninguno
bar el recurso.
scope Ámbito de la variable no page
anterior.
Ejemplo:
<fmt:setBundle basename="ApplicationResources"/>
<fmt:message key="welcome.user"/>
fmt:setLocale
Table 33.
Atributo Descripción Requerido Por defecto
value Nombre del locale, o sí ninguno
instancia de
36
JSTL
El valor del locale se compone del código del lenguaje según el ISO-639
[http://www.loc.gov/standards/iso639-2/englangn.html] y el código del país según el ISO-3166
[http://www.iso.ch/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html] separados
por un carácter de subrayado.
Ejemplo:
Si no establecemos un locale con esta etiqueta, el valor por defecto es el enviado por la cabecera
Accept-Language del navegador. Si tal cabecera no esta presente se toma el locale de la
máquina virtual donde se ejecuta el contenedor JSP.
fmt:requestEncoding ??
Formateo
fmt:formatNumber
Funciona como c:out pero permitiendo más control sobre el formato. Su uso básico es
<fmt:formatNumber value="${variable}"/>
que hace lo mismo que c:out pero comprueba el idioma del navegador (lo lee a través de la
cabecera Accept-Language) para mostrar correctamente la cantidad.
Por ejemplo, este código muestra el idioma preferente del navegador y formatea un número:
<c:out value="${header['Accept-Language']}"/>
<fmt:formatNumber value="1234567.89"/>
es 1.234.567,89
en 1,234,567.89
Table 34.
Atributo Descripción Requerido Por defecto
value Valor numérico a form- no cuerpo
atear.
type Si mostrar números, no number (puede ser
monedas, o porcentajes. number, currency,
o percent)
currencyCode Código de moneda no ningúno
ISO-2417 (ver bsi-
37
JSTL
38
JSTL
Ejemplo de patrón:
1.2345679E6
<fmt:formatNumber value="1234567.89" pattern="##0.#####E0"/>
fmt:formatDate
No acepta valores en el cuerpo. Requiere un atributo value con una variable que represente una
fecha (conviene usar fmt:parseDate). Un modo rápido de crear una variable con una fecha es
instanciar java.util.Date como bean:
Table 35.
Atributo Descripción Requerido Por defecto
value Fecha a mostrar. sí ningúno
type Si mostrar fechas, horas no date (puede ser
o ambos. date, time, o both)
dateStyle Estilo preferido para la no default (puede ser
fecha. default, short,
medium, long)
timeStyle Estilo preferido para el no default (puede ser
tiempo. default, short,
medium, long)
timeZone Zona horaria usada para no Posibles valores
formatear la fecha. [http://www.timeanddat
e.com/library/abbreviati
ons/timezones/]
39
JSTL
El atributo timeZone permite especificar la zona horaria de una fecha. Puede tomar como valor
cualquier abreviatura de las zonas horarias
[http://www.timeanddate.com/library/abbreviations/timezones/].
5:25:33 PM
<fmt:formatDate value="${now}" type="time" timeStyle="default"/>
5:25 PM
<fmt:formatDate value="${now}" type="time" timeStyle="short"/>
5:25:33 PM
<fmt:formatDate value="${now}" type="time" timeStyle="medium"/>
5:25:33 PM CEST
<fmt:formatDate value="${now}" type="time" timeStyle="long"/>
40
JSTL
Table 36.
Caracter Descripción Ejemplo
yy Año corto. 02
yyyy Año completo. 2002
M Número del més. 4
MM Número de més con dos dígitos. 04
MMM Nombre corto del més. Apr
MMMM Nombre del més. April
d Día del mes. 5
dd Día del més con dos dígitos. 05
EE Nombre corto del día. Fri
EEEE Nombre del día. Friday
H Hora en formato militar. 21
HH Hora en formato militar con dos 21
dígitos.
h Hora (1-12). 9
hh Hora (1-12) con dos dígitos. 09
m Minuto. 4
mm Minuto con dos dígitos. 04
s Segundo. 6
ss Segundo con dos dígitos. 06
S Milisegundo. 249
a AM / PM PM
zz Nombre corto de zona horaria. EST
zzzz Zona horaria. Eastern Standard Time
Z Descripción de zona horaria. -0500
'cadena' Cadena a incluir. 'cadena'
Ejemplos de patrones:
Table 37.
Patrón Resultado
yyyy.MM.dd G 'at' HH:mm:ss z 2004.09.05 AD at 18:06:56 CEST
EEE, MMM d, ''yy Sun, Sep 5, '04
h:mm a 6:06 PM
hh 'o''clock' a, zzzz 06 o'clock PM, Central European
Summer Time
K:mm a, z 6:06 PM, CEST
yyyyy.MMMMM.dd GGG hh:mm aaa 02004.September.05 AD 06:06 PM
EEE, d MMM yyyy HH:mm:ss Z Sun, 5 Sep 2004 18:06:56 +0200
yyMMddHHmmssZ 040905180656+0200
fmt:parseNumber
41
JSTL
Interpreta cadenas como números. Es necesario para pasar valores numéricos a algunas etiquetas
como sql:param, fmt:formatNumber, y otras.
Table 38.
Atributo Descripción Requerido Por defecto
value Cadena a interpretar no cuerpo
como número.
type Como interpretarlo. no number (puede ser
number, currency,
o percent)
integerOnly Si descartar decimales. no false
pattern Patrón de formato. no ningúno. Ver SimpleD-
ateFormat
[http://java.sun.com/j2s
e/
1.4.2/docs/api/java/text/
SimpleDate-
Format.html].
parseLocale Locale a usar. no
var Variable en la que gra- no ningúno
bar el resultado.
scope Ámbito de la variable no page
anterior.
Ejemplo:
fmt:parseDate
Interpreta cadenas como fechas. Usa el locale del contenedor JSP.
Table 39.
Atributo Descripción Requerido Por defecto
value Fecha a mostrar. no cuerpo
type Si mostrar fechas, horas no date
o ambos.
dateStyle Estilo preferido para la no default (puede ser
fecha. default, short,
medium, long)
timeStyle Estilo preferido para el no default (puede ser
tiempo. default, short,
medium, long)
timeZone Zona horaria usada para no Ningúno. Posibles
formatear la fecha. valores
[http://www.timeanddat
e.com/library/abbreviati
ons/timezones/].
pattern Patrón de formateo. no Ningúno. Ver SimpleD-
42
JSTL
fmt:setTimeZone
Permite cambiar la zona horaria:
Table 40.
Atributo Descripción Requerido Por defecto
value Identificador de la zona sí Ninguno. Posibles
horaria, o instancia de valores
java.util.TimeZo [http://www.timeanddat
ne. e.com/library/abbreviati
ons/timezones/].
var Variable en la que no ningúno
guardar la zona horaria.
scope Ámbito de la variable. no page
Los posible valores del atributo value son los correspondientes al método estático
java.util.TimeZone.getAvailableIDs().
Ejemplo:
<fmt:setTimeZone value="GMT"/>
fmt:timeZone
Permite cambiar temporalmente la zona horaria. Se usa colocando en el cuerpo de la etiqueta, las in-
strucciones que queremos que se ejecuten en la nueva zona horaria.
Table 41.
Atributo Descripción Requerido Por defecto
value Identificador de la zona sí Ningúno. Posibles
horaria. valores
[http://www.timeanddat
e.com/library/abbreviati
ons/timezones/].
Ejemplo:
43
JSTL
<fmt:timeZone value="GMT">
<jsp:useBean id="ahora" class="java.util.Date"/>
<fmt:formatDate value="${ahora}"/>
</fmt:timeZone>
XML
XPath en JSTL
La librería XML de JSTL usa XPath para obtener partes de los documentos XML con que opera. Si
no conoces XPath, hay un pequeño tutorial en la última sección de este documento.
En JSTL, cuando una expresión XPath devuelve algún nodo, se considera true, si no, false.
Una variable XPath tiene el formato $nombre, o el formato $nombre1:nombre2. Por ejemplo:
$sessionScope:usuario. En JSTL podemos usar los siguientes espacios de nombres para las
variables:
Table 42.
Prefijo Significado
pageScope variables de ámbito página
requestScope variables de ámbito request
sessionScope variables de ámbito session
applicationScope variables de ámbito application
param parametros del request como cadenas
header cabeceras del request http como cadenas
initParam parametros de inicialización del contexto
cookie valores de las cookies
x:parse
Antes de poder usar un fichero XML debemos interpretarlo, o dicho en spanglish, parsearlo. Parsear
es el proceso de analizar la sintaxis de la información y convertirla a un formato más manejable.
Table 43.
Atributo Descripción Requerido Por defecto
xml Texto XML a parsear. no cuerpo
Debe ser una cadena o
una instancia de
java.io.Reader.
var Nombre de la variable no ningúno
con la que exponer el
documento. El objeto
resultante cumple el in-
terfaz
org.w3c.dom.Docu
ment.
scope Ámbito con el que ex- no page
poner la variable anteri-
44
JSTL
<x:parse var="noticiasRDF">
<c:import url="http://www.javahispano.org/noticias.rdf"/>
</x:parse>
Tras ejecutar el c:import anterior aparece un documento XML en el cuerpo. Tambien podemos
escribirlo explicitamente:
<x:parse var="transmision">
<correo>
<de>hal9000@discovery.gov</de>
<mensaje>All these worlds are yours except europa.</mensaje>
</correo>
<x:parse>
x:out
Evalúa y muestra el resultado de una expresión XPath.
Table 44.
Atributo Descripción Requerido Por defecto
select Expresión XPath. sí --
escapeXml Muestra ciertos carac- no true
teres como entidades.
Ejemplo:
45
JSTL
<x:parse var="mailfeed">
<mail>
<received>
<from>mta04ps.bigpond.com</from>
<by>smtp01-01.mesa1.secureserver.net</by>
</received>
<received>
<from>lerc-daemon.mta04ps.email.bigpond.com</from>
<by>mta04ps.email.bigpond.com</by>
</received>
<subject>[SPAM] CONGRATULATION LUCKY WINNER</subject>
</mail>
</x:mail>
<x:out select="$mailfeed/mail/subject"/>
x:set
Guarda el resultado de una expresión XPath en una variable.
Table 45.
Atributo Descripción Requerido Por defecto
select Expresión XPath. sí --
var Variable en la que no ningúno
guardar el resultado de
la expresión XPath.
scope Ámbito en el que expo- no page
ner la variable anterior.
Ejemplo:
<x:parse var="DecentralizingREST">
<dissertation>
<title>
Extending the REpresentational State Transfer (REST)
Architectural Style for Decentralized Systems
</title>
<author>
<first>Rohit</first>
<last>Kare</last>
</author>
</dissertation>
</x:parse>
<x:set var="autor" select="$DecentralizingREST/dissertation/author"/>
x:if
Table 46.
46
JSTL
Hay motivos por los que es útil guardar la expresión en una variable:
Ejemplo:
<x:parse var="RESTpapers">
<paper>
<dissertation>
<title>
Extending the REpresentational State Transfer (REST)
Architectural Style for Decentralized Systems
</title>
<author>
<first>Rohit</first>
<last>Kare</last>
</author>
</dissertation>
</paper>
</x:parse>
<x:if select="$RESTpapers/paper//author/last[text()='Kare'">
At least one paper from Rohit Kare.
</x:if>
Table 47.
Atributo Descripción Requerido Por defecto
select Expresión XPath a sí ninguno
evaluar. Si es true
procesa el cuerpo.
En el ejemplo que vimos en la etiqueta anterior, usariamos este código para mostrar un mensaje
según el autor de cada documento:
<x:choose>
<x:when select="$RESTpapers/paper//author/last[text()='Kare'">
47
JSTL
x:forEach
Se usa para iterar sobre los elementos XML resultantes de ejecutar una expresión XPath.
Table 48.
Atributo Descripción Requerido Por defecto
select Expresión XPath sobre sí ningúno
cuyos resultados vamos
a iterar.
var Nombre de la variable no ningúno
con la que exponer el
nodo actual.
En cada iteración, el elemento correspondiente sirve de contexto respecto al que hacen referencia to-
das las expresiones del cuerpo. Si se anidan las etiquetas x:forEach, las etiquetas internas haran
referencia al contexto de la iteración de la etiqueta externa.
<x:parse var="RESTpapers">
<paper>
<dissertation>
<title>
Extending the REpresentational State Transfer (REST)
Architectural Style for Decentralized Systems
</title>
<author>
<first>Rohit</first>
<last>Kare</last>
</author>
</dissertation>
</paper>
</x:parse>
<x:forEach select="$RESTpapers//title">
<p><x:out select="."/></p>
</x:forEach>
En el atributo select de las etiquetas foreach y out podemos usar cualquier expresión XPath.
Ahora un ejemplo que lee muestra una lista con las últimas noticias
[http://www.javahispano.org/noticias.rdf] de javaHispano [http://www.javahispano.org]:
48
JSTL
<li>
<a href="<x:out select="./*[name()='link']"/>">
<x:out select="./*[name()='title']" />
</a>
</li>
</x:forEach>
</ul>
x:transform
La etiqueta x:trasform sirve para aplicar XSLT al XML.
Table 49.
Atributo Descripción Requerido Por defecto
result ?? [PENDIENTE] ?? ??
scope Ámbito con el que ex- no page
poner la variable anteri-
or.
var Nombre de la variable no ninguno
con la que exponer el
documento resultante.
El objeto resultante
cumple el interfaz
org.w3c.dom.Docu
ment.
xml Documento XML a no cuerpo
transformar. Debe ser
una cadena o una in-
stancia de
java.io.Reader.
xslt Hoja de estilo XSLT a sí --
aplicar.
Ejemplo:
Puedes encadenar transformaciones, por ejemplo, docbook --> javahispano --> XHTML -->
XHTML + CSS :
<x:transform xslt="${summerStyle}">
<x:transform xslt="${jh2xhtml}">
<x:transform xslt="${docbook2jh}" xml="${docbook}"/>
</x:transform>
49
JSTL
</x:transform>
Podemos definir el xml y xsl dentro de la misma página: [PENDIENTE: copiar transformación del
informe]
<c:set var="xml">
...[PENDIENTE]
</c:set>
<c:set var="xsl">
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
...[PENDIENTE]
</xsl:stylesheet>
</c:set>
<x:transform xml="${xml}" xslt="${xsl}"/>
x:param
Permite declarar parametros para su uso en hojas de estilo. Una hoja de estilo XSLT puede declarar
variables con la etiqueta <xsl:param> y también aceptarlos de fuentes externas a la hoja de es-
tilo.
Table 50.
Atributo Descripción Requerido Por defecto
name nombre del parametro sí ninguno
value valor del parametro no cuerpo
Los parámetros permiten personalizar hojas de estilo. Como ejemplo, estos son los posibles
parámetros [http://docbook.sourceforge.net/release/xsl/current/doc/html/] de las hojas de estilo Doc-
book XSL. Normalmente, los parametros XSL se añaden incluyendo una hoja de estilo que los con-
tiene. Aqui, como en otras ocasiones, JSTL se revela adecuado solo para un uso improvisado.
Ejemplo:
<x:param name="draft.mode">no</x:param>
¿Como funciona?
• Antes de compilar un JSP, el contenedor transforma la página JSP en un documento JSP, que es
50
JSTL
la versión equivalente en XML. Ver JSP 2.0 The New Deal Part 3
[http://www.onjava.com/pub/a/onjava/2004/04/21/JSP2part3.html] acerca de esto.
• El documento XML se crea con un elemento jsp:id por cada elemento de la página. Cada uno de
estos ids esta referenciado desde un Map, que les asocia información (fichero, línea, y columna)
que permite identificar su origen en la página JSP.
• Si alguna de las etiquetas del documento JSP tiene asociado un TLV, el contenedor ejecuta di-
cho TLV.
TLVs de JSTL
Si hemos instalado JSTL, los dos TLVs que proporciona estarán disponibles. Su implementación es-
ta en el paquete javax.servlet.jsp.jstl.tlv
[http://java.sun.com/webservices/docs/1.0/api/javax/servlet/jsp/jstl/tlv/package-summary.html]. Son
estos:
• ScriptFree: Permite restringir los elementos de scripting de una página JSP. Sus parametros son:
<validator>
<validator-class>
javax.servlet.jsp.jstl.tlv.PermittedTaglibsTLV
</validator-class>
<init-param>
<param-name>permittedTaglibs</param-name>
<param-value>
http://java.sun.com/jstl/core
http://java.sun.com/jstl/fmt
http://java.sun.com/jstl/sql
http://java.sun.com/jstl/xml
</param-value>
51
JSTL
<description>
Whitespace-separated list of taglib URIs to permit.
This example TLD for the Standard Taglib allows
only JSTL 'el' taglibs to be imported.
</description>
</init-param>
</validator>
Con la línea anterior indicamos el uso de ScriptFreeTLV con los parametros que figuran en el
fichero scriptfree.tld (todo a false). Si queremos personalizarlo podemos editar ese .tld y co-
piar el elemento validator al tld de nuestras etiquetas, ajustando los parametros según nos convenga.
Las bibliotecas JSTL tienen sus propios TLVs, que no tiene sentido reutilizar pues están diseñados
especificamente para validar etiquetas JSTL. Por ejemplo, la librería core usa el TLV Jstl-
CoreTLV. Podemos verlo leyendo el fichero c.tld contenido en el jar
standard-1.0.4.jar:
...
<validator>
<validator-class>
org.apache.taglibs.standard.tlv.JstlCoreTLV
</validator-class>
<description>
Provides core validation features for JSTL tags.
</description>
</validator>
...
Observese que carece de parametros, porque no esta pensado para su uso por el usuario.
Repaso a XPath
Esta sección es un repaso rápido a XPath. Si quieres experimentar mientras estudias, puedes usar
XPath Explorer [http://www.purpletech.com/xpe/index.jsp] de Alex Chaffe.
¿Que es XPath?
• XPath es la especificación de una sintaxis con la que referirse a partes de un documento XML.
• XPath incluye funciones para trabajar con cadenas, números, y expresiones booleanas.
• XPath fue publicado por el W3C con categoría de “tecnología recomendada” en Noviembre de
1999.
Selección
Seleccionar nodos
Hay varias similitudes entre el sistema de ficheros unix y los documentos XML:
52
JSTL
• Una referencia absoluta a un elemento comienza con el carácter (/), una referencia relativa no.
• Para seleccionar un elemento sin tener en cuenta su nombre usamos asterisco (*).
Table 52.
expresión selecciona
/email/cuerpo/p El primer elemento párrafo (p) hijo de cuerpo.
/email/cuerpo/../cuerpo/p Lo mismo dando un rodeo.
./p Lo mismo suponiendo que cuerpo sea el nodo
actual.
/email/cuerpo/* Todos los hijos del cuerpo.
/email/*/p Todos los párrafos nietos del elemento email.
/*/*/p Todos los párrafos nietos de la raíz.
//* Todos los elementos.
Table 53.
expresión selecciona
//p Cualquier elemento p descendiente de la raíz.
/email/cuerpo//p Cualquier elemento p descendiente del cuerpo.
Ejemplo:
53
JSTL
Table 54.
expresión selecciona
//p | //a Todos los párrafos y enlaces a cualquier nivel.
Filtrar con []
Podemos usar paréntesis cuadrados para especificar criterios que deben satisfacer los elementos a
buscar.
Table 55.
expresión selecciona
/email/cuerpo/p[1] Primer párrafo hijo de cuerpo. En XPath el
primer elemento es uno, no cero como en java.
/email/cuerpo/p[last()] Último párrafo hijo de cuerpo (hemos usado una
función XPath).
/email/cuerpo[p] Todos los elementos cuerpo hijos de email y con
un elemento p.
/email[to=Jano] Los elementos email con hijo to igual a Jano.
/email[to=Jano]/to Todos los elementos to con contenido Jano.
Table 56.
expresión selecciona
//p[@color="azul"] todos los párrafos con atributo color igual a rojo
//p[@*] todos los párrafos con cero o más atributos
//p[@color] todos los párrafos con atributo color
//@color todos los atributos color
Resumen de operadores
Table 57.
Operador Función
* Selecciona todos sus elementos sin tener en
cuenta su nombre.
. Nodo actual.
.. Nodo padre.
@ Selecciona todos los atributos sin tener en cuenta
su nombre.
/ Separador entre elementos. Cuando aparece al
principio indica que los hijos deben ser selec-
54
JSTL
Operador Función
cionados a partir del nodo raíz.
// Especifica una búsqueda sobre cualquier descen-
diente.
[condicion] Desprecia los elementos seleccionados que no
cumplen la condición dada.
Ejemplos varios
Table 58.
Ejemplo Resultado
. Nodo actual.
.. Padre del nodo actual.
p Hijo p del nodo actual.
//p Todos los hijos p del nodo raíz.
* Cualquier hijo del nodo actual.
*/p Todos los nietos p del nodo actual.
@* Cualquier atributo del nodo actual.
../@href Atributo href del padre del nodo actual.
text() todos los nodos de texto del nodo actual
p[1] Segundo hijo p del nodo actual (segundo hijo, no
el nieto).
p[last()] Último hijo p del nodo actual.
/email/cuerpo/p[1]/a[2] Segundo enlace del primer párrafo hijo del ele-
mento cuerpo.
a[@href="#N101AF"] Enlace hijo del nodo actual con atributo href
igual a #N101AF.
div[@id="noticia"][2] Segundo hijo div del nodo actual con atributo
id igual a noticia.
div[@user="jano" or Todos los hijos div del nodo actual con atribute
@user="jano-r"] user igual a jano o jano-r.
Expresiones XPath
Son las compuestas con los operadores +, –, *, div, mod, = (igualdad), !=, <, <=, >, >=, or, and.
Métodos
Funciones Node Set
Table 59.
Nombre Descripción
count() Devuelve el número de elementos seleccionados.
id() Selecciona elementos por su id único.
last() Devuelve un número igual al tamaño del con-
55
JSTL
Nombre Descripción
texto donde se evalua la expresión.
local-name() Devuelve la parte local del nombre expandido
del nodo en el conjunto de nodos del argumento
que es el primero en el orden del documento.
name() Devuelve el nombre de un elemento.
namespace-uri() Devuelve la URI del espacio de nombres del
nombre expandido del nodo en el conjunto de
nodos del argumento que es el primero en el or-
den del documento.
position() Devuelve un número igual a la posición del con-
texto desde el contexto de la expresión evaluada.
Funciones de cadena
Table 60.
Atributo Descripción Ejemplo Resultado
concat() Devuelve la concat('hola',' hola mundo
concatenación de sus ','mundo')
argumentos
contains() Devuelve true si la contains('hola true
primera cadena con- mundo','hola')
tiene la segunda;
false en caso con-
trario.
normalize- Quita espacios al comi- normalize- hola mundo
space() enzo y final. space(' hola
mundo ')
starts-with() Devuelve true si la starts- true
primera cadena comi- with('hola
enza con la segunda, o mundo','hol')
false en caso con-
trario.
starts-with() Convierte un objeto a string(123.45) 123,45
cadena.
string-length() Devuelve el número de string- 10
caracteres de una ca- length('hola
dena. mundo')
substring() Devuelve una sub- substring('hola hola
cadena. mundo',1,4)
substring- Devuelve la subcadena substring- mundo
after() tras otra subcadena. after('hola
mundo',' ')
substring-be- Devuelve la subcadena substring-be- hola
fore() anterior a otra sub- fore('hola
cadena. mundo',' ')
translate() Reemplaza una cadena translate('hola hol4 mundo
por otra. mundo','a','4')
Funciones numéricas
56
JSTL
Table 61.
Atributo Descripción Ejemplo Resultado
ceiling() Devuelve el entero más ceiling(12.3) 13
pequeño y no menor
que el argumento.
floor() Devuelve el entero más floor(12.3) 12
grande pero no mayor
que el argumento.
number() Devuelve el número number(4) 4
correspondiente a su ar-
gumento.
round() Devuelve el entero más round(12.3) 12
próximo al argumento.
sum() Devuelve la suma res- sum(.)
ultante de sumar el con-
junto de nodos que
pasamos como para-
metro.
Funciones booleanas
Table 62.
Atributo Descripción Ejemplo Resultado
boolean() Convierte su argumento
a boolean.
false() Devuelve false false() false
true() Devuelve true.
false() Devuelve true si el not(false()) true
argumento es false y
viceversa.
true() Devuelve true. true() true
Espacios de nombres
Supongamos un documento como
57
JSTL
cios de nombres (que son sinónimos de sus respectivas URIs) los usa internamente el documento
pero no podemos usarlos nosotros.
58