Está en la página 1de 82

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-1-

Captulo 15:
Introduccin a JSP
* El estndar HTML propone el suministro de informacin
mediante pginas estticas. De esta forma es imposible
suministrar pginas creadas al momento en base a requisitos del
cliente. Ej: consultar una base de datos desde una pgina HTML
y obtener otra pgina automticamente slo con los resultados
deseados.
* Otras tecnologas empleadas tradicionalmente han sido CGI,
ASP, PHP.

S
* Las principales ventajas de JSP sobre ellas son:

Mayor encapsulamiento:G
T Uso de clases
T Uso de JavaBeans
R

Mayor escalabilidad

Uso de tags: similitud con HTML


Mayor portabilidad
Uso de un lenguaje estndar y muy difundido

* El lenguaje en que actualmente est basado JSP es Java


* Realmente una pgina JSP se convierte en un servlet que es
quien se encarga de la comunicacin con el cliente

Captulo 15: Introduccin a JSP.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-2-

Funcionamiento
* Cul es el funcionamiento bsico? Muy sencillo:
1) El cliente solicita una pgina .jsp (en lugar de .html)
2) La solicitud llega al servidor
3) El servidor ejecuta la pgina .jsp y obtiene un texto en
formato html
4) El servidor enva el texto html al cliente
5) El navegador del cliente visualiza el texto html como si
realmente hubiera estado almacenado en el servidor
* Que hay dentro de un fichero .jsp?
Un fichero .jsp es un fichero .html que tiene dentro
algunas cosas que se pueden ejecutar y que producen
como resultado ms html
* El siguiente dibujo resume el funcionamiento:

* Realmente, la solicitud de la pgina JSP le llega (en nuestros


ejemplos) al motor JSP a travs del puerto 8080
Captulo 15: Introduccin a JSP.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-3-

Instalacin
* El motor o servidor JSP puede ser el JSWDK, o bien Apache
Tomcat
* Usaremos Tomcat ya que tiene soporte para tags. JSWDK no
* Consideraciones de instalaciones de Tomcat:

Quitar el start de la invocacin a javac en tomcat.bat

Al comienzo de startup.bat poner: set


JAVA_HOME=d:\jdk1.3

El puerto de escucha se puede modificar en


/conf/server.xml

Los servlets se ubican en /WEB-INF/classes

Los ficheros .jsp y .tld se encuentran a partir de ROOT

Tomcat no acepta la etiqueta bodycontent en un fichero


.tld

Modificar el classpath para que se encuentren todos los


.class necesarios, especialmente jdk1.3/lib/tools.jar

Cuando se usan etiquetas, los ficheros .class que heredan


de Tag deben pertenecer a un paquete

Tomcat se arranca con startup

Es conveniente crear en el directorio ROOT un directorio


jsp para guardar las pginas JSP

La ubicacin de los ficheros .tld se puede indicar a travs


del fichero /conf/web.xml

S
G
R

* Estas consideraciones de instalacin son


buen funcionamiento del servidor Tomcat

Captulo 15: Introduccin a JSP.

bsicas para el

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-4-

Componentes JSP
* Los componentes que se pueden meter enmedio de una pgina
HTML para hacerla dinmica (hacerla JSP) son:

Expresiones: son de la forma:


<%= expresin Java %>
El motor traduce la expresin por la cadena que resulta de
evaluarla
Declaraciones: son de la forma:
<%! declaraciones Java %>
Lo que se escriba aqu ser global a toda la pgina JSP
(realmente se inserta tal cual en el cuerpo del servlet fuera
de todo mtodo)
Pueden incluirse declaraciones de variables y de funciones
Scriplets: son de la forma:
<% cdigo Java %>
Cdigo Java que se ejecutar en el punto concreto de la
pgina JSP en que se encuentra

Captulo 15: Introduccin a JSP.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-5-

Componentes JSP
L

Comentarios: son de la forma:


<%-- comentario %>
No se envan al cliente
Directivas: son de la forma:
<%@ directiva atributo1=" valor1"
atributo2=" valor2" ... %>
Permiten definir la estructura de todo el documento JSP.
Realmente indican aspectos bsicos del servlet en que se
convertir el fichero JSP en que se encuentra. Se procesan
en el momento de convertir la pgina JSP en un servlet.
Las tres directivas existentes son:
O <%@ page ... %>
O <%@ include file=URL relativa %>
Sirve para incluir un fichero dentro de otro en el
momento en que la pgina JSP se convierte en servlet
O <%@ taglib ... %>

S
G
R

Etiquetas jsp: son de la forma:


<jsp:etiqueta atributos />
Realizan operaciones diversas. Su utilidad principal es para
comunicarse con los JavaBeans de forma que el cdigo
dela pgina .jsp sea lo ms parecido al .html

Captulo 15: Introduccin a JSP.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-6-

Primer ejemplo
* El ejemplo ms sencillo consiste en cambiarle la extensin a
cualquier fichero .html y ponerle .jsp, as como colocarlo en un
sitio donde el servidor JSP la pueda encontrar. As de sencillo!
* Con esto lo nico que conseguimos es que la pgina nos la
sirva el servidor JSP en lugar del servidor web
* Una vez visto que todo funciona bien, podemos probar con
algo sencillo, tal como
<HTML>
<HEAD>
<TITLE>Expresiones JSP</TITLE>
</HEAD>
<BODY>
<H2>Expresiones JSP</H2>
<UL>
<LI>Fecha actual: <%= new java.util.Date().toLocaleString() %>
<LI>Su mquina: <%= request.getRemoteHost() %>
<LI>Su ID de sesin: <%= session.getId() %>
<LI>El parmetro <CODE>testParam</CODE>:
<%= request.getParameter("testParam") %>
</UL>
</BODY>
</HTML>

* Esta pgina puede ser llamada como:


http://localhost:8080/jsp/Ejemplo.jsp
o como
http://localhost:8080/jsp/Ejemplo.jsp?testParam=alguna+cosa

Captulo 15: Introduccin a JSP.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-7-

Expresiones JSP
* Las pginas JSP son especialmente itles cuando el usuario
enva un formulario lleno de campos en los que expresa el tipo
de informacin que solicita
* Los parmetros que enva el usuario se pueden conocer
enviando el mensaje getParameter(String) al objeto request,
que es uno de los varios objetos que el motor JSP nos suministra
para que tengamos mayor control.
* Los objetos ms tiles que se nos suministran son:

request de tipo HttpServletRequest. Representa la


solicitud realizada por el cliente

response de tipo HttpServletResponse. Representa


nuestra respuesta. no tiene porqu ser una pgina html sino
cualquier otra cosa (ver setContentType())

session de tipo HttpSession. Representa la sesin del


cliente

out de tipo JspWriter (es un PrintWriter con buffer). Es


el ms utilizado y representa el canal de salida de texto y
datos hacia el cliente

application de tipo ServletContext. Con setAttribute y


getAttribute sirve para guardar objetos globales a todas las
pginas JSP

pageContext de tipo PageContext. Muy utilizado en las


etiquetas para obtener el resto de objetos anteriores (que no
son visibles en las etiquetas)

S
G
R

Captulo 15: Introduccin a JSP.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-8-

Scriptlets
* Un scriptlet es un trozo de cdigo Java
* Si se ha comprendido bien el fichero .jsp anterior, se puede
comprender lo que hace un scriplet (y el funcionamiento del
objeto out) viendo la siguiente equivalencia:
<LI>Fecha actual: <%= new java.util.Date().toLocaleString() %>

equivale a
<%
String fecha new java.util.Date().toLocaleString();
out.println(<LI>Fecha actual: +fecha);
%>

* Un ejemplo ms completo puede ser:


<HTML>
<HEAD><TITLE>Prueba de colorines</TITLE></HEAD>
<%
// Cuidado con maysculas y minsculas
String bgColor = request.getParameter("bgColor");
boolean hasExplicitColor;
if (bgColor != null) {
hasExplicitColor = true;
} else {
hasExplicitColor = false;
bgColor = "WHITE";
}
%>
<BODY BGCOLOR="<%= bgColor %>">
<H2 ALIGN="CENTER">Color Testing</H2>
<%
if (hasExplicitColor) {
out.println("Has indicado como color de fondo " + bgColor + ".");
} else {
out.println("Color de fondo por defecto BLANCO. " +
"Indique un valor para el atributo bgColor, " +
"que puede ser una cadena RRVVAA, o un color estndar " +
"si su navegador soporta colores X11.");
}
%>
</BODY>
</HTML>

Captulo 15: Introduccin a JSP.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-9-

Scriptlets y condiciones
* Un scriptlet puede estar formado por varios trozos. Lo que hay
entre ellos se considera cuerpo del scriptlet aunque sea cdigo
HTML.
* Ejemplo:
<HTML>
<HEAD>
<TITLE>Cuerpos dentro de bloques JSP</TITLE>
</HEAD>
<BODY>
<H1>Cuerpos dentro de <i>Scriptlets</i></H1>
<% if (Math.random() < 0.5) {%>
Que tenga un buen da.
<% } else { %>
Que tenga mucha suerte.
<% } %><p>
Y ahora la tabla del 7:<br>
<% for (int i = 1; i <= 10; i++) { %>
7 x <%= i %> = <%= 7*i %> Perfecto <br>
<% } %>
</BODY>
</HTML>

S
G
R

Captulo 15: Introduccin a JSP.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-10-

Declaraciones
* En las declaraciones se pueden incluir funciones y variables
que pueden utilizarse en cualquier lugar de la pgina
<HTML>
<HEAD><TITLE>Declaracin de funciones</TITLE></HEAD>
<%!
void tabla(JspWriter out, int numero){
for (int i = 1; i <= 10; i++)
try{
out.print(numero + " x " + i + " = " + numero*i+"<br>");
} catch (IOException ioe){ioe.printStackTrace();}
}
%>
<BODY><H1>Declaracin de funciones</H1>
Ahora la tabla del 7 y luego la del 4:<br>
<%
tabla(out, 7);
out.print("<p>");
tabla(out, 4);
%>
</BODY>
</HTML>

* Una vez que la pgina JSP se carga en memoria por parte del
servidor JSP se queda en ella (a menos que se modifique, en
cuyo caso se recompila). Ej. que lo demuestra:
<HTML>
<HEAD><TITLE>Declaracin de variables en JSP</TITLE></HEAD>
<%!
private int accesos = 0;
%>
<BODY><H1>Declaracin de variables en JSP</H1>
<H2>Accesos a esta pgina desde que se carg el servidor:

<%= ++accesos %>


</H2>
</BODY>
</HTML>

Punto indicado

* Probar a cargar la pgina varias veces. Luego quitar el punto


indicado y volverla a cargar varias veces
Captulo 15: Introduccin a JSP.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-11-

Directiva page. Atributos


* La directiva page se aplica a toda la pgina en que se
encuentra. Permite los siguientes atributos:

import. Permite hacer uso de paquetes Java, de manera


anloga a como se importa en un programa Java. Se puede
importar un solo package o varios separndolos por comas

contentType. Permite indicar el tipo de los datos que se


van a enviar al cliente enformato MIME

isThreadSafe. Una pgina JSP se puede ejecutar varias


veces simultneamente antes peticiones de clientes
concurrentes. Si se indica isThreadSafe=false las
peticiones se resuelven secuencialmente

session. Un valor false indica que el objeto session no


existe y se producir un error en el momento de convertir
la pgina en servlet si se intenta utilizar

buffer. Cuando el servidor JSP enva la respuesta al cliente


utiliza un buffer intermedio. Con este atributo se indica su
tamao en kB, o bien la palabra none si no se quiere usar
buffer

autoflush. El buffer se enva al cliente de forma automtica


cada vez que se llena. Si se indica false se produce un error
de overflow si el buffer se llega a llenar

extends. Se usa para crear una pgina JSP que hereda de la


clase que se indique en este atributo

errorPage. Sirve para indicar la URL de una pgina que se


enviar al cliente en lugar de la actual si, por cualquier
circunstancia, sta se rompe

isErrorPage. Indica si la pgina actual es o no una pgina


de suministro elegante de errores

S
G
R

Captulo 15: Introduccin a JSP.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-12-

Ejemplo con page


Fichero EjemploPage.jsp
<HTML>
<HEAD><TITLE>Comparacin entre peras y manzanas</TITLE></HEAD>
<BODY><CENTER>
<H2>Comparacin entre peras y manzanas</H2>
<%@ page errorPage="Error.html" %>
<%
String formato = request.getParameter("formato");
// Si el parmetro no existe se eleva un NullPointerException
if (formato.equals("excel")) {
response.setContentType("application/vnd.ms-excel");
} else {
response.setContentType("text/plain");
}
%>
<TABLE BORDER=1>
<TR><TH></TH><TH>Peras<TH>Manzanas
<TR><TH>Primer trimestre<TD>2307<TD>4706
<TR><TH>Segundo trimestre<TD>2982<TD>5104
<TR><TH>Tercer trimestre<TD>3011<TD>5220
<TR><TH>Cuarto trimestre<TD>3055<TD>5287
</TABLE>
</CENTER></BODY>
</HTML>

Fichero Error.html
<HTML><BODY>
Esta pgina se obtiene en lugar del error tradicional
<BODY><HTML>

Captulo 15: Introduccin a JSP.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-13-

Ejemplo de upload
* Para subir ficheros al servidor, fotos, etc. se puede usar el
paquete com.oreilly.servlet.*: es muy til la clase
MultipartRequest, ya que el formulario de envo debe ser
multiparte.
Fichero upload.jsp
<%@ page import="com.oreilly.servlet.*, java.util.*, java.io.*" %>
<%
try{
MultipartRequest multi = new MultipartRequest(request, ".",10000000);// .10MB
out.println(multi.getParameter("line")+"<br>");
out.println("Files:");
Enumeration files = multi.getFileNames();
while (files.hasMoreElements()) {
String name = (String)files.nextElement();
String filename = multi.getFilesystemName(name);
String type = multi.getContentType(name);
File f = multi.getFile(name);
if (f==null) continue; // Por si el parmetro no est cargado
BufferedReader in = new BufferedReader(new FileReader(f));
String s, s2 = new String();
while((s = in.readLine())!= null)
s2 += s + "<br>";
out.println("name: " + name);
out.println("filename: " + filename);
out.println("type: " + type);
out.println("f.length(): " + f.length()+"<br>");
out.println("fileContent: " + s2+"<br>");
in.close();
}
}catch(IOException e){
//No es un error, sino tan slo la primera vez que se llama a esta pgina
}
%>

S
G
R

<FORM ENCTYPE="multipart/form-data" method="POST" action="upload.jsp">


<INPUT TYPE="text" NAME="line">
<INPUT TYPE="file" NAME="mptest">
<INPUT TYPE="submit" VALUE="upload">
</FORM>

Captulo 15: Introduccin a JSP.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-1-

Captulo 16:
Etiquetas jsp: y JavaBeans
* Las etiquetas jsp: difieren de las directivas en que son
interpretadas para cada peticin del cliente y, por tanto, se
pueden considerar una etiqueta HTML ms.
* Las etiquetas jsp: existentes son:

jsp:include. Se utiliza para incluir ficheros en situaciones


condicionales (a diferencia de la directiva @ include que
los incluye siempre). Adems, permite no slo incluir
ficheros, sino los resultados de otros servlets, pginas JSP,
etc. El resultado incluido NO puede contener JSP

jsp:forward. Hace que la pgina actual no sea la que se


enve al cliente, sino la que se especifique en el forward.
A este respecto hay que considerar lo siguiente: En el
momento en que la pgina actual responda al cliente lo ms
mnimo ya no es posible hacer un forward, pues se
produce un error. Es por ello que JSP utiliza un buffer (por
defecto de 8 kB).

S
G
R

* El formato de ambas etiquetas es muy parecido:


<jsp:include page=URLRelativa flush=true>
<jsp:param name=nombreParmetro value=valor>
...
</jsp:include>
* En el forward el atributo flush no existe, mientras que en el
include es oblitarorio y adems siempre true.

Captulo 16: Etiquetas jsp: y JavaBeans.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-2-

Ejemplo de jsp:page
* Con el cuerpo opcional jsp:param es posible enviar campos
al formulario destino.
Fichero includes.jsp
<HTML><BODY>
<H1>Includes selectivos</H1>
Lo que se incluye a partir de aqu se va alternando.
<%! boolean biestable = true; %>
<%
biestable = !biestable;
if (biestable) {
%>
<jsp:include page="uno.jsp" flush="true">
<jsp:param name="color" value="red"/>
</jsp:include>
<% } else { %>
<jsp:include page="dos.html" flush="true"/>
<% } %>
</BODY></HTML>

Fichero uno.jsp
<%
String bgColor = request.getParameter("color");
if (bgColor == null)
bgColor = "WHITE";
String texto = request.getParameter("texto");
if (texto == null)
texto = "Prueba de color";
%>
<H2 ALIGN="CENTER">
<FONT COLOR="<%= bgColor %>" ><%= texto %></FONT>
</H2>

Fichero dos.html
<H1>Esto es un ejemplo de algo que se incluye</H1>

* Ntese como en uno.jsp se utiliza tanto el atributo recibido


por includes.jsp como el que ste le enva. Invocar includes.jsp
de la forma:
http://betelgeuse:8080/jsp/includes.jsp?texto=prueba
Captulo 16: Etiquetas jsp: y JavaBeans.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-3-

La etiqueta jsp:plugin
* Es transformada automticamente por el servidor JSP en una
etiqueta que incluye un applet que puede utilizar las extensiones
del JDK 1.2 y superiores (no es necesario que se haya
descargado el plug-in de Java para los navegadores).
* Su formato es muy parecido al de la etiqueta APPLET. Un
ejemplo comparativo puede ser:
<APPLET CODE=MiApplet.class
WIDTH=465
HEIGHT=350>
</APPLET>

equivale a

S
G
R
* Si el applet tiene parmetros, stos se pasan igual que en
<jsp:plugin type=applet
code=MiApplet.class
width=465"
height=350">
</jsp:plugin>

jsp:include, aunque deben ir, a su vez, entre <jsp:params> y


</jsp:params>
* Adems de losmismo atributos que permite la etiqueta
APPLET, otros atributos que posee son:

jreversion. Versin del JRE que requiere el applet

nspluginurl. La URL completa en la que es posible


encontrar el plug-in para Netscape

iepluginurl. La URL completa en la que es posible


encontrar el plug-in para Internet Explorer
* Adems de applets tambien se pueden cargar JavaBeans
Captulo 16: Etiquetas jsp: y JavaBeans.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-4-

Uso de JavaBeans
* Desde nuestro punto de vista, un JavaBean es una clase con
las siguientes caractersticas:

Posee un constructor sin parmetros

No posee campos pblicos

Para conocer el valor de un campo llamado xxx debe


disponer de una funcin getXxx (o isXxx si es de tipo
boolean)

Para asignarle valor a un campo llamado xxx debe disponer


de una funcin setXxx
* La utilizacin de los JavaBeans permite encapsular diversas
funcionalidades aumentando la orientacin a objetos del sistema
* Para no ensuciar el cdigo HTML de la pgina JSP, se
suministran varias etiquetas jsp: que permiten gestionar los
JavaBeans de forma natural
* Las etiquetas jsp: para gestionar JavaBeans son:

jsp:useBean. Crea un objeto (si no existe ya) de una clase


que cumple ser un JavaBean y le da un nombre. A partir de
este momento ese objeto se utilizar por su nombre

jsp:setProperty. Invoca un mtodo setXxx de un


JavaBean previamente creado

jsp:getProperty. Visualiza el resultado devuelto por un


mtodo getXxx de un JavaBean previamente creado

Captulo 16: Etiquetas jsp: y JavaBeans.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-5-

Sintaxis
* Los atributos que admite jsp:useBean son:
id=nombre. Nombre que se le da a ese objeto
scope=page|request|session|application. Indica dnde se
puede usar dicho objeto:
O page: slo en esta pgina
O request: si hay un forward o un include tambin se
podr usar en las pginas destino
O session: se puede usar en la sesin de usuario a travs de
varias pginas, pero slo para ese usuario
O application: Existir hasta que se cierre el servidor JSP.
Disponible para todo el mundo siempre.
class=Clase.class. Nombre de la clase de la que se crea el
objeto
type=Clase.class. Por si se quiere hacer un upcasting

S
G
* Los atributos que admite jsp:getProperty
son:
R
name=nombre. Nombre del objeto del que tomar el campo

property=nombreCampo. Nombre del campo cuyo valor se


desea visualizar
* Los atributos que admite jsp:setProperty son:
name=nombre. Nombre del objeto en que guardar el valor
property=NombreCampo. Nombre del campo cuyo valor se
desea guardar
value=valor. Valor que se desea guardar. Se hace una
conversin automtica en funcin del tipo del campo

Captulo 16: Etiquetas jsp: y JavaBeans.

Programacin en Java. Forman, 2000.

-6-

Ejemplo de JSP y JavaBeans


Fichero StringBean.java
/** Un JavaBean sencillito que slo tiene un campo
* llamado mensaje de tipo String
*/
package jsp;
public class StringBean {
private String mensaje = "Ningn mensaje";
public String getMensaje() {
return(mensaje);
}
public void setMensaje(String mensaje) {
this.mensaje = mensaje;
}
}

Fichero StringBean.jsp
<HTML>
<HEAD><TITLE>Uso de JavaBeans con JSP</TITLE></HEAD>
<BODY>
<TABLE BORDER=5 ALIGN="CENTER">
<TR><TH CLASS="TITLE">Uso de JavaBeans con JSP
</TABLE>
<jsp:useBean id="stringBean" class="jsp.StringBean" />
<OL>
<LI>Valor inicial (getProperty):
<I><jsp:getProperty name="stringBean" property="mensaje" /></I>
<LI>Valor inicial (expresin JSP):
<I><%= stringBean.getMensaje() %></I>
<LI><jsp:setProperty name="stringBean" property="mensaje"
value="El mejor lenguaje: Java" />
Valor despus de haber cambiado el campo con setProperty:
<I><jsp:getProperty name="stringBean" property="mensaje" /></I>
<LI><% stringBean.setMensaje("Libertad, Igualdad y Fraternidad"); %>
Valor despus de haber cambiado el campo con un <i>scriptlet</i>:
<I><%= stringBean.getMensaje() %></I>
</OL>
</BODY>
</HTML>

* El nombre dado al JavaBean puede usarse desde un scriptlet


* El StringBean.class debe ir en el directorio WEB-INF\classes
de la aplicacin donde est metida la pgina StringBean.jsp.
Captulo 16: Etiquetas jsp: y JavaBeans.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-7-

Asignacin de parmetros
* Si una pgina recibe parmetros que hay que asignarlos a
campos de un JavaBean, jsp:setProperty suministra una forma
de hacerlo de forma elegante. De esta guisa, los dos trozos de
cdigo siguientes son equivalentes:
<%
int numElementos = 1;
try {
numElementos = Integer.parseInt(request.getParameter(num));
} catch (NumberFormatException nfe) {}
%>
<jsp:setProperty

name=articulo
property=numero
value=<%= numElementos %>

/>

S
G
* El atributo param en lugarRde value toma el valor de un
parmetro de entrada a la pgina JSP, lo convierte al tipo del
equivale a

<jsp:setProperty

name=articulo
property=numero
param=num

/>

campo y guarda su valor en el campo.


* Para asociar todos los parmetros de entrada con campos de un
JavaBean basta con indicar un asterisco como property. Ej.:
<jsp:setProperty

name=articulo
property=*

/>

* En ste ltimo caso, los nombres de los parmetros y de los


campos del JavaBean han de ser idnticos

Captulo 16: Etiquetas jsp: y JavaBeans.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-8-

Ejemplo
Fichero StringBean2.java
/** Un JavaBean sencillito que slo tiene un campo
* mensaje de tipo String y un campo dato de tipo double
*/
package jsp;
public class StringBean2 {
private String mensaje = "Ningn mensaje";
private double dato = 0.0;
public String getMensaje() { return(mensaje); }
public void setMensaje(String mensaje) { this.mensaje = mensaje; }
public double getDato() { return(dato); }
public void setDato(double dato) { this.dato = dato; }
}

Fichero StringBean2.jsp
<HTML>
<HEAD><TITLE>Uso de JavaBeans con JSP</TITLE></HEAD>
<BODY>
<jsp:useBean id="articulo" class="jsp.StringBean2" scope ="session" />
<% if (request.getParameter("mensaje") != null) { %>
<jsp:setProperty name="articulo" property="*" />
<jsp:getProperty name="articulo" property="mensaje" /><br>
<jsp:getProperty name="articulo" property="dato" /><br>
<% } else {%>
<FORM ACTION="StringBean2.jsp">
<INPUT TYPE="TEXT" NAME="mensaje" VALUE="Algo que contar">
<INPUT TYPE="TEXT" NAME="dato" VALUE="67.9">
<INPUT TYPE="SUBMIT">
</FORM>
<% } %>
</BODY>
</HTML>

* Como se dijo antes, con jsp:useBean se crea un objeto si ste


no exista ya. Si ya exista se usa el preexistente y ya est
* Entre <jsp:useBean ...> y </jsp:useBean> se puede introducir
un bloque JSP que slo se ejecutar si el JavaBean se crea de
verdad
Captulo 16: Etiquetas jsp: y JavaBeans.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-1-

Captulo 17:
Biblioteca de etiquetas (Tags)
* Permiten construir pginas JSP con una estructura ms
parecida a la del HTML.
* Se utilizan etiquetas de la misma forma que en HTML.
* Las etiquetas pueden tener parmetros y englobar un cuerpo.
* Las etiquetas funcionalmente relacionadas se agrupan en
ficheros llamados bibliotecas de etiquetas.

S
* Cada etiqueta se asocia a un bloque de cdigo Java ubicado en
la clase cuyo nombre se indica.
G
* Estas clases deben heredar y utilizar clases estndares
R
almacenadas en el paquete java.servlet.jsp.tagext.*
* Cuando el motor JSP se encuentra una de estas etiquetas, la
sustituye por su cdigo asociado y lo ejecuta.
* Por tanto, necesitamos tres ficheros:

La pgina JSP que utiliza las etiquetas: *.jsp

La clase que contiene el cdigo a ejecutar: *.class

Un fichero que indica qu clase se corresponde con cada


etiqueta: *.tld (Tag Library Descriptor)

* En el cdigo asociado podemos acceder al objeto


pageContext y, a travs de l, a los objetos out, request,
parameter, etc.
Captulo 17: JSP y bibliotecas de etiquetas.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-2-

Primer ejemplo
Fichero ExampleTag.java
package jsp;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.io.*;
/** Utilizacin de etiquetas con JSP. Ejemplo que saca un sencillo mensaje.
* El nombre real de la etiqueta no se da aqu, sino en el fichero tld referenciado
* en la pgina JSP a travs de la directiva taglib
*/
public class ExampleTag extends TagSupport {
public int doStartTag() {
try {
JspWriter out = pageContext.getOut();
out.print("Custom tag example (ExampleTag)");
} catch(IOException ioe) {
System.out.println("Error in ExampleTag: " + ioe);
}
return(SKIP_BODY);
}
}

Fichero csajsp-taglib.tld
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib PUBLIC "-//Sun MicroSystems, Inc.//DTD JSP Tag Library 1.1//EN"
"http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>1.1</jspversion>
<shortname>csajsp</shortname>
<info>http://www.coreservlets.com/.</info>
<tag>
<name>example</name>
<tagclass>ExampleTag</tagclass>
<info>Simplest example: inserts one line of output</info>
</tag>
</taglib>

Fichero Ejemplo.jsp
<HTML>
<HEAD>
<%@ taglib uri="/csajsp-taglib.tld" prefix="csajsp" %>
<TITLE><csajsp:example /></TITLE>
</HEAD>
<BODY><H1><csajsp:example /></H1><csajsp:example /></BODY>
</HTML>
Captulo 17: JSP y bibliotecas de etiquetas.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-3-

La clase Tag
* Las etiquetas se forman por un inicio, un cuerpo y un final.
Cuando el sistema se encuentra el inicio ejecuta doStartTag(),
y cuando encuentra el final ejecuta doEndTag().
* Estas funciones deben reescribirse en una clase que hereda de
la interfaz Tag. Sun suministra dos clases de partida que heredan
de Tag:
O TagSupport, si la etiqueta no gestiona el cuerpo
O BodyTagSupport, si se quiere tener un control completo
del cuerpo
* doStartTag() retorna un entero que puede ser:
SKIP_BODY. Ignora lo que haya entre el inicio de etiqueta
y el final de etiqueta. Contina con el resto de la pgina
EVAL_BODY_INCLUDE. Evala el cuerpo que haya entre
el inicio de etiqueta y el final de etiqueta. Slo TagSupport
EVAL_BODY_TAG. Igual que el anterior, pero con ms
control. Slo BodyTagSupport

S
G
R

* doEndTag() retorna un entero que puede ser:


SKIP_PAGE. Ignora el resto de la pgina HTML
EVAL_PAGE. Contina normalmente la evaluacin del
resto de la pgina
* Como en cualquier otra etiqueta HTML, las etiquetas pueden
tener atributos asociados. Si una etiqueta tiene asociado el
atributo miAtributo, el sistema (antes de llamar a doStartTag())
busca y llama automticamente a una funcin llamada
setMiAtributo(String) y que deberemos definir en la clase
asociada a la etiqueta.
Captulo 17: JSP y bibliotecas de etiquetas.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-4-

Tag Library Descriptor


* El fichero *.tld tiene estructura del fichero XML conforme al
estndar
http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd
* La primera parte del fichero es comn para todos ellos.
* La etiqueta <taglib> engloba todas las etiquetas que vamos a
definir en este fichero. Contiene:
<tlibversion> La versin de este tld
<jspversion> La versin ms pequea con que funciona este
tld
<shortname> Prefijo que se debe usar cuando se referencien
las etiquetas de este tld. (No obligatorio)
<uri>
URI donde se encuentra este tld
<info>
Descripcin de este tld.
<tag>
Diferentes etiquetas definidas en este biblioteca.
Contiene:
<name>
Nombre de la etiqueta
<tagclass>
Fichero .class asociado a la etiqueta
<teiclass>
Fichero .class opcional, subclase de
TagExtraInfo
<bodycontent>
Puede contener tres valores:
EMPTY Debe estar vaco
JSP
Posee cualquier cosa vlida en una
pgina .jsp
TAGDEPENDENT
El contenido ser
interpretado por el cdigo del .class
<info>
Descripcin opcional de esta etiqueta
<attribute>
Diferentes atributos que puede contener
esta etiqueta. Contiene:
Captulo 17: JSP y bibliotecas de etiquetas.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-5-

Tag Library Descriptor


<attribute>

Diferentes atributos que puede contener


esta etiqueta. Contiene:
<name>
Nombre del atributo
<required>
Si el atributo es obligatorio o no
<rtexprvalue> Indica si el valor del atributo debe ser
constante, o si puede ser una expresin
JSP que vare de una ejecucin a otra
de la pgina

* Los atributos son siempre de tipo String y es necesario


convertirlos a su tipo correcto controlando posibles errores.

S
* Para utilizar una biblioteca se emplea la directiva taglib que
posee como parmetros:
G
uri
La direccin del fichero .tld que contiene la
traduccin de las etiquetas. Direccin a partir del
R
directorio ROOT
prefix

Prefijo que deben tener todas las etiquetas que


procedan del uri anterior. Se utiliza para evitar
conflictos de etiquetas procedentes de varios tld

* La ubicacin de un fichero .tld se puede indicar a travs del


fichero de configuracin web.xml, de la forma:
<taglib>
<taglib-uri>/myPRlibrary</taglib-uri>
<taglib-location>/WEB-INF/tlds/PRlibrary_1_4.tld</taglib-uri>
</taglib>

de forma que en el fichero JSP se puede invocar simplemente


como:
<%@ taglib uri=/myPRlibrary prefix=x %>

Captulo 17: JSP y bibliotecas de etiquetas.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-6-

Segundo ejemplo
Fichero SimpleTag.java
package jsp;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.io.*;
import java.util.*;
/** Utilizacin de etiquetas con JSP. Ejemplo que saca un nmero aleatorio
* entre 0 y el parmetro que se le pasa.
*/
public class SimpleTag extends TagSupport {
protected long maximo = 100;
public int doStartTag() {
try {
JspWriter out = pageContext.getOut();
out.print(new Random().nextLong() % maximo);
} catch(IOException ioe) {
System.out.println("Error in SimpleTag: " + ioe);
}
return(SKIP_BODY);
}
public void setMaximo(String maximo){
try{
this.maximo = new Long(maximo).longValue();
} catch(NumberFormatException nfe){
this.maximo=100;
}
}
}

Tag del fichero csajsp-taglib.tld


<tag>
<name>example3</name>
<tagclass>jsp.SimpleTag</tagclass>
<info>Saca un numero aleatorio por la salida</info>
<attribute>
<name>maximo</name>
<required>false</required>
</attribute>
</tag>

Ejemplo de uso
<csajsp:example3 maximo="10000"/>

Captulo 17: JSP y bibliotecas de etiquetas.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-7-

Etiquetas con cuerpo


* El cuerpo se encuentra entre el inicio de etiqueta y el final de
etiqueta:
<prefijo:etiqueta>cuerpo</prefijo:etiqueta>
* El cuerpo puede contener cualquier componente de los que
hay en el resto de la pgina
Si no se desea un control especial sobre el cuerpo de una
etiqueta, no es necesario heredar de BodyTagSupport, sino que
en doStartTag() retornamos SKIP_BODY o
EVAL_BODY_INCLUDE

S
* En el siguiente ejemplo se observa como es posible retornar
cualquiera de sendas etiquetas
en base a un condicin de
G
depuracin
R
* Podemos invocar a la pgina como:
http://localhost:8080/jsp/EjemploDebug.jsp
o bien como:
http://localhost:8080/jsp/EjemploDebug.jsp?debug=si
segn queramos que aparezca el cuerpo o no

* Ntese como el cuerpo tambin puede contener elementos JSP

Captulo 17: JSP y bibliotecas de etiquetas.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-8-

Tercer ejemplo. Depuracin


Fichero DebugTag.java
package jsp;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.io.*;
import javax.servlet.*;
/* Utilizacin de etiquetas con JSP. Ejemplo que evala el cuerpo o no
* en funcin de un parmetro de formulario llamado debug.
*/
public class DebugTag extends TagSupport {
public int doStartTag() {
ServletRequest request = pageContext.getRequest();
String debugFlag = request.getParameter("debug");
if ((debugFlag == null) || (debugFlag.equalsIgnoreCase("no")))
return SKIP_BODY;
else
return EVAL_BODY_INCLUDE;
}
}

Fichero EjemploDebug.jsp
<HTML>
<HEAD><TITLE>Using the Debug Tag</TITLE></HEAD>
<BODY>
<H1>Uso de la etiqueta depurar</H1>
<%@ taglib uri="/WEB-INF/tlds/csajsp-taglib.tld" prefix="csajsp" %>
Comienzo de pgina. Bla, bla, bla. chiu, chiu, chiu.<P>
<csajsp:depurar>
<B>Debug:</B>
<UL>
<LI>Fecha actual: <%= new java.util.Date().toLocaleString() %>
<LI>Host remoto: <%= request.getRemoteHost() %>
<LI>Id de Sesin: <%= session.getId() %>
</UL>
</csajsp:debug>
<P>
Final de pgina. Bla, bla, bla. chiu, chiu, chiu.<P>
</BODY>
</HTML>

Captulo 17: JSP y bibliotecas de etiquetas.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-9-

Manipulacin del cuerpo


* Si se hereda de BodyTagSupport se incorporan varios mtodos
nuevos:
T doInitBody(). Se invoca automticamente antes de la primera
evaluacin dle cuerpo
T doAfterBody(). Se invoca automticamente despus de cada
evaluacin del cuerpo. Puede retornar:
SKIP_BODY. Finaliza la ejecucin del cuerpo
EVAL_BODY_TAG. Reevala el cuerpo
De esta forma el cuerpo se evala una y otra vez mientras
doAfterBody() retorne EVAL_BODY_TAG

S
T getBodyContent(). Devuelve
Gun objeto de tipo BodyContent
* Un objeto de tipo BodyContent representa el resultado de
R
haber evaluado el cuerpo de una etiqueta. Los cuerpos se

evalan y el resultado se mete en un BodyContent. A


continuacin, el BodyContent se suele volcar en out.
BodyContent posee los siguientes mtodos:

getString(). Devuelve una cadena que representa la


evaluacin del cuerpo

getReader(). Permite leer a travs de un Reader el


BodyContent

clearBody(). Resetea el contenido del BodyContent

getEnclosingWriter()

writeOut(Writer). Vuelca el contenido del BodyContent en


el Writer especificado

Captulo 17: JSP y bibliotecas de etiquetas.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-10-

Ejemplo de bucle
Fichero RepeatTag.java
package jsp;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.io.*;
/* Etiqueta que repite el cuerpo un nmero de veces.
*/
public class RepeatTag extends BodyTagSupport {
private int reps;
public void setReps(String repeats) {
try {
reps = Integer.parseInt(repeats);
} catch(NumberFormatException nfe) {
reps = 1;
}
}
public int doAfterBody() {
if (reps-- >= 1) {
BodyContent body = getBodyContent();
try {
JspWriter out = body.getEnclosingWriter();
out.println(body.getString());
body.clearBody(); // Borra para el ciclo siguiente
} catch(IOException ioe) {
System.out.println("Error en RepeatTag: " + ioe);
}
return(EVAL_BODY_TAG);
} else {
return(SKIP_BODY);
}
}
}

Tag del fichero csajsp-taglib.tld


<tag>
<name>repetir</name>
<tagclass>jsp.RepeatTag</tagclass>
<info>Ejecuta el cuerpo varias veces</info>
<attribute>
<name>reps</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>

Captulo 17: JSP y bibliotecas de etiquetas.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-11-

mbito de objetos
Fichero RepetirEjemplo.jsp
<HTML>
<HEAD><TITLE>Algunos nmeros aleatorios</TITLE></HEAD>
<BODY>
<H1>Algunos nmeros aleatorios</H1>
Cada nmero de la lista siguiente es un nmero aleatorio
<%@ taglib uri="/WEB-INF/tlds/csajsp-taglib.tld" prefix="csajsp" %>
<OL>
<!-- Se repite N veces. Si reps es null se repite una sola vez. -->
<csajsp:repetir reps='<%= request.getParameter("repeats") %>'>
<LI><csajsp:example3 maximo="1000000" />
</csajsp:repetir>
</OL>

S
* Como se observa en este yG
anteriores ejemplos, el nmero
aleatorio que se obtiene es siempre el mismo, ya que por cada
invocacin de una etiqueta seR
vuelve a crear un objeto de su
</BODY>
</HTML>

clase asociada. Si un objeto se quiere reutilizar de una


invocacin a otra en la misma pgina, se puede almacenar en el
objeto request con:
request.setAttribute(clave, objeto)
y se recupera con request.getAttribute(clave)
* Ejemplo que soluciona el problema (SimpleTag.java)
JspWriter out = pageContext.getOut();
ServletRequest request = pageContext.getRequest();
Random rnd = (Random) request.getAttribute("rnd");
if (rnd == null){
rnd = new Random();
request.setAttribute("rnd", rnd);
out.println("Creando el Random()");
}
out.print(rnd.nextLong() % maximo);
Captulo 17: JSP y bibliotecas de etiquetas.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-12-

Etiquetas anidadas
* Hay situaciones en las que se sabe que una etiqueta debe
aparecer siempre dentro del cuerpo de alguna otra. La etiqueta
exterior puede contener alguna informacin til para las internas
* Desde una etiqueta interna podemos acceder al objeto de la
externa mediante la funcin:
Object findAncestorWithClass(Object, Class)
* Los parmetros definen de quin se busca la etiqueta ancestro
(normalmente this) y, por si el anidamiento es de varios niveles,
que tipo de etiqueta ancestro es la que se busca (p.ej.
EtiquetaExterna.class)

Captulo 17: JSP y bibliotecas de etiquetas.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-13-

Bases de Datos
* En este ejemplo completo se ilustra la utilizacin de una base
de datos mediante el uso de etiquetas anidadas
*El cdigo JSP producido es muy similar al HTML con la
ventaja con respecto a la legibilidad que ello conlleva
* Las etiquetas que se usan son:
T queryBlock que toma como parmetros el nombre de la
fuente de datos (en ODBC). Opcionalmente podra incluir
el nombre de usuario y la clave
T queryStatement que tiene como cuerpo el texto de una
consulta SQL
T queryCreateRows que prepara la lectura del nmero de
tuplas que se indique desde un inicio a un final (ambos
opcionales)
T queryDisplay que visualiza el contenido del campo que
se indique

S
G
R

* Ejemplo de uso:
<html>
<%@ taglib uri=http://acme.com/taglibs/simpleDB.tld prefix=x %>
<x:queryBlock connData=conData1>
<x:queryStatement>
SELECT nombre, apellidos FROM Clientes
</x:queryStatement>
Los primeros diez clientes son:
<table>
<tr><th>ACCOUNT</th><th>BALANCE</th></tr>
<x:queryCreateRows from=1 to=10>
<tr> <td><x:queryDisplay field=nombre/></td>
<td><x:queryDisplay field=apellidos/></td>
</tr>
</x:queryCreateRows>
</table>
</x:queryBlock>
</html>
Captulo 17: JSP y bibliotecas de etiquetas.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-14-

Etiquetas Java
Fichero QueryBlockTag.java
package jsp;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.sql.*;
import java.io.*;
class Util {
public static void prueba(JspWriter out, String cadena){
try {
out.print(cadena);
}catch(IOException ioe){
ioe.printStackTrace();
}
}
}
public class QueryBlockTag extends TagSupport{
protected Connection conexin;
protected ResultSet resultado;
private String connData = "prueba1";
JspWriter out ;
public void setConnData(String connData){
this.connData = connData;
}
public int doStartTag(){
try{
out = pageContext.getOut();
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
conexin = DriverManager.getConnection("jdbc:odbc:"+connData, "", "");
}catch(Exception e){
e.printStackTrace();
Util.prueba(out, "Error en la apertura de la base de datos");
return SKIP_BODY;
}
return EVAL_BODY_INCLUDE;
}
public int doEndTag(){
try{
conexin.close();
}catch(SQLException se){se.printStackTrace();}
return EVAL_PAGE;
}
}

Captulo 17: JSP y bibliotecas de etiquetas.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-15-

Etiquetas Java
Fichero QueryStatementTag.java
package jsp;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.sql.*;
import java.io.*;
public class QueryStatementTag extends BodyTagSupport{
public int doAfterBody(){
BodyContent body = getBodyContent();
try{
QueryBlockTag padre = (QueryBlockTag)findAncestorWithClass(this,
QueryBlockTag.class);
if (padre ==null) throw new SQLException("Padre es null");
Statement sentencia = padre.conexin.createStatement();
padre.resultado = sentencia.executeQuery(body.getString());
}catch(SQLException se){
Util.prueba(body.getEnclosingWriter(), "No se puede crear la sentencia.");
}
return SKIP_BODY;
}
}

S
G
Fichero QueryDisplayTag.java
R
package jsp;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.sql.*;
import java.io.*;

public class QueryDisplayTag extends TagSupport{


private String field;
public int doStartTag(){
ResultSet resultado = ((QueryBlockTag)findAncestorWithClass(this,
QueryBlockTag.class)).resultado;
JspWriter out = pageContext.getOut();
try{
out.print(resultado.getString(field));
}catch(Exception ioe){
Util.prueba(out, "Imposible cargar el campo: "+ field);
}
return SKIP_BODY;
}
public void setField(String field){ this.field = field;
}
}
Captulo 17: JSP y bibliotecas de etiquetas.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-16-

Etiquetas Java
Fichero QueryCreateRowsTag.java
package jsp;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.sql.*;
import java.io.*;
public class QueryCreateRowsTag extends BodyTagSupport{
int from = 1, to = 1;
ResultSet resultado;
public void setFrom(String from){ this.from = Integer.parseInt(from);}
public void setTo(String to){
this.to = Integer.parseInt(to);
}
public int doStartTag(){
re s u lt a d o
=
((Q u e ryB lo c kT ag)f indAncest o rW it h Cla s s (t h is,
QueryBlockTag.class)).resultado;
int contador = 1;
// Este bucle se posiciona en el registro anterior al que hay que mostrar
try{
while ((contador < from) && resultado.next()) contador ++;
}catch(SQLException se){
se.printStackTrace();
}
try{
if(!resultado.next()) return SKIP_BODY;
}catch(SQLException se){
Util.prueba(pageContext.getOut(), "No se puede mostrar el registro");
return SKIP_BODY;
}
return EVAL_BODY_TAG;
}
public int doAfterBody(){
BodyContent body = getBodyContent();
JspWriter out = body.getEnclosingWriter();
try{
out.print(body.getString());
body.clearBody();
}catch(IOException ioe){Util.prueba(out, "Imposible emitir registro"); }
if (++from > to) return SKIP_BODY;
else{
try{ if (!resultado.next()) return SKIP_BODY;
}catch(SQLException sqle){
Util.prueba(out, "Error en los registros.");
return SKIP_BODY;
}
return EVAL_BODY_TAG;
}
}
}

Captulo 17: JSP y bibliotecas de etiquetas.

Programacin en Java. Cursos de verano, Accin Estudiantil, 2003.

-17-

Descriptor de etiquetas
Fichero bbdd-taglib.tld
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib PUBLIC "-//Sun MicroSystems, Inc.//DTD JSP Tag Library 1.1//EN"
"http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>1.1</jspversion>
<shortname>bbdd</shortname>
<info>http://www.coreservlets.com/.</info>
<tag>
<name>queryBlock</name>
<tagclass>jsp.QueryBlockTag</tagclass>
<info>Comienzo de una consulta. Conexin</info>
<attribute>
<name>connData</name>
<required>false</required>
</attribute>
</tag>
<tag>
<name>queryStatement</name>
<tagclass>jsp.QueryStatementTag</tagclass>
<info>Ejecuta una consulta que es su propio cuerpo</info>
</tag>
<tag>
<name>queryCreateRows</name>
<tagclass>jsp.QueryCreateRowsTag</tagclass>
<info>Se posiciona al comienzo de la tupla deseada</info>
<attribute>
<name>from</name>
<required>false</required>
</attribute>
<attribute>
<name>to</name>
<required>false</required>
</attribute>
</tag>
<tag>
<name>queryDisplay</name>
<tagclass>jsp.QueryDisplayTag</tagclass>
<info>Visualiza el campo que se indica</info>
<attribute>
<name>field</name>
<required>false</required>
</attribute>
</tag>
</taglib>

S
G
R

Captulo 17: JSP y bibliotecas de etiquetas.

Programacin en Java. Universidad de Mlaga, 2006.

-1-

Captulo 18:
JSTL
(Java Standard Tag Library)
* El objetivo de JSTL (biblioteca de etiquetas estndar de Java)
es facilitar el trabajo a los desarrolladores de JSP.
* Desde un punto de vista general, JSTL proporciona las
siguientes capacidades:
O Acciones de propsito general mediante un lenguaje de
expresiones, atributos con mbito y captura de excepciones
O Acciones de control de flujo dentro de una pgina JSP
O Validaciones de bibliotecas de etiquetas que obligan a
que un proyecto cumpla con ciertas reglas de estilo

S
G
R

* Desde el punto de vista de las bibliotecas concretas que


suministra, JSTL nos da las siguientes:
O Etiquetas de propsito general (gestin de variables)
O Etiquetas de control de flujo y de iteracin
O Etiquetas asociadas a URLs
O Etiquetas de internacionalizacin y formateo
O Etiquetas para trabajar con bases de datos
O Etiquetas para trabajar con XML
O Etiquetas de manipulacin de cadenas
* Como se ver a lo largo de nuestro estudio, JSTL utiliza
ciertas convenciones que hacen ms fcil al desarrollador el
recordar la estructura interna de las etiquetas.

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-2-

Lenguaje de expresiones
* El lenguaje de expresiones (EL) sirve para facilitar la escritura
de expresiones restringidas Java dentro de una pgina JSP.
* Una expresin EL se escribe de la forma
${expresion}
y entre las llaves puede usarse cualquier operador binario o
unario que se quiera, ya sea matemtico, de cadena, relacional
o lgico. Es muy til el operador unario empty para saber si
algo es null o no.
* Como operandos pueden usarse:

Variables con mbito.

Literales numricos, de cadena o lgicos.

Componentes Java Beans.

Colecciones.

Funciones definidas en un fichero .tld


* La gran ventaja de las expresiones EL es que son evaluadas
por el propio motor JSP que las sustituye bajo demanda por el
resultado de la evaluacin. Por tanto, las expresiones pueden
usarse en cualquier lugar de una pgina JSP:
T Como sustituta de un literal HTML
T Como valor de un atributo de una etiqueta
* Ejemplos:
${10 mod 3}
devuelve 1
${1 > 3}
devuelve false
<c:set var=numeroSS value=124578" />
${numeroSS == 124578}
devuelve true
Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-3-

Contenido de expresiones
* Una expresin EL unifica el uso del punto y de los corchetes.
De esta guisa, expr-a.ident-b es equivalente a expr-a[identb].
* Para evaluar expr-a[expr-b] se evala expr-a a valor-a y
expr-b a valor-b, y en base a valor-a se hacen diferentes
acciones:

Si es null el resultado es null.

Si es de tipo Map, se retorna valor-a.get(valor-b).

Si es de tipo List el resultado es valor-a.get((int)valor-b).

Si es un array el resultado es Array(.get(valor-a, valorb).

Si es un Java Bean se retorna la propiedad valor-b.

S
G
R

* Las siguientes variables pueden usarse directamente (todas son


listas):

param: lista con los nombres de los parmetros.

paramValues: lista con los valores de los parmetros.

header: lista con los campos de la cabecera.

headerValues: lista con los valores de los campos de la


cabecera.

cookie: lista con los nombres de las cookies.

pageScope, requestScope, sessionScope y


applicationScope: lista con las variables definidas en cada
mbito.
* Ejemplo:
<c:forEach item=unaCookie values=${cookie}>
${unaCookie}<br>
</c:forEach>
Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-4-

Core Tag Library


* Esta biblioteca posee etiquetas de propsito general, entre las
que se incluyen las de manipulacin de variables y gestin de
errores. El prefijo estndar para esta biblioteca es c. Para usarla
hay que incluir en la pgina JSP:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"
%>
* Las etiquetas ms importantes que posee son:
O <c:out> utilizada con el mismo objetivo que el scriptlet
<%= expresion %> tiene algunas funcionalidades
adicionales
O <c:set> permite asignar valores a variables (p.ej., de
sesin) o a propiedades de Java Beans
O <c:remove> es el complemento natural al anterior, y
sirve para destruir variables con mbito
O <c:catch> permite recuperar un error, y supone el
complemento perfecto para la pgina de error JSP
O <c:if> emite por la salida el cuerpo que contiene slo si
la condicin a que se refiere es cierta
O <c:choose>, <c:when> y <c:otherwise> permiten
formar una estructura de ifs en cascada con parte else
O <c:forEach> permite recorrer una coleccin o un array,
as como ejecutarse como un bucle FOR de BASIC
O <c:forTokens> divide una cadena en trozos y se ejecuta
para cada trozo
* Las etiquetas de URL tambin forman parte de las core pero
las veremos aparte por su complejidad.
Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-5-

<c:out>
* La sintaxis de esta etiqueta es:
<c:out value=valor
[escapeXml=true|false]
[default=valorSiEsNull]
/>
* Emite por la salida el valor del atributo value. Si este es nulo,
se saca por pantalla el valor del atributo default.

S
G
R

* Por defecto escapeXml est puesto a true, lo que quiere decir


que se traducen algunos caracteres para evitar errores:
Carcter
<
>
&

Cdigo de carcter
&lt;
&gt;
&amp;
&#039;
&#034;

* El valor dado al atributo value se convierte en String y se


emite, a no se que sea un objeto de tipo java.io.Reader, en cuyo
caso lo que se emite es el resultado de leer por completo dicho
canal de entrada.
* Puede probarse como ejemplo con la pgina completa:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:out value="Trabajo en Gar & ca" />

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-6-

<c:out> y Reader
* Sea el siguiente Bean:
package org.apache.jsp;
import java.io.*;
public class StringBean {
private String nombreFichero = "Ningun nombreFichero";
public String getNombreFichero() {
return(nombreFichero);
}
public void setNombreFichero(String nombreFichero) {
this.nombreFichero = nombreFichero;
}
public Reader getLector() throws IOException {
return new FileReader(getNombreFichero());
}
public void setLector(String lector) {
this.nombreFichero = lector;
}
}

* Y el JSP:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<jsp:useBean id="stringBean"
class="org.apache.jsp.StringBean" />
<jsp:setProperty
name="stringBean"
property="lector"
value="e:/prueba.txt"
/>
<c:out value="${stringBean.lector}"/><br>
<c:out value="Otra cosa" /><br>

* La salida de la lnea marcada es el contenido del fichero


e:\prueba.txt. De una sola tacada se ha emitido el contenido de
un fichero entero.

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-7-

<c:set> y <c:remove>
* La sintaxis de <c:set> es:
O Para asignar valor a una variable con mbito
<c:set value=valor
var=nombreVar
[scope=page|request|session|application]
/>
O Para asignar una propiedad a un Java Bean, o un elemento
de un mapa
<c:set value=valor
target=nombreVar
property=nombrePropiedad
/>
O Para establecer un valor en diferido. Un valor diferido
quiere decir que se asigna una expresin que se evala de forma
perezosa, o sea, no en este momento, sino cuando se utilice la
variable. Realmente esto slo tiene utilidad cuando se trabaja
con JSF (Java Server Faces) y no volveremos a tratar el tema.

S
G
R

* <c:remove> slo tiene sentido para variables con mbito. La


sintaxis de <c:remove> es:
<c:remove var=nombreVar
[scope=page|request|session|application]
/>
* <c:set> hace asignaciones a variable con mbito o a
propiedades de Java Beans o a datos de Mapas. <c:remove>
elimina variables con mbito.
* El subrayado quiere decir que slo pueden especificarse
literales.

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-8-

<c:catch>
* La sintaxis de <c:catch> es:
<c:catch [var=nombreVar]>
// Acciones que pueden producir excepciones
</c:catch>
* <c:catch> permite capturar excepciones dentro de bloques
JSP.
* La idea es que los errores graves no sean capturados, sino que
se propaguen hasta la pgina de error especificada. Los errores
secundarios son los que se deben capturar con <c:catch> para
que no interfieran con el desarrollo normal de la pgina.
* Si se indica un nombre de variable, entonces la excepsin se
guarda en ella. Si no se produce excepcin, entonces esa
variable se destruye con <c:remove> si es que exista. Por
tanto, lo que suele venir a continuacin del <c:catch> es una
accin condicional que testa dicha variable para hacer la accin
correctora que sea.
* Sino se quiere incluir accin correctora, entonces incluso
puede omitirse el atributo var de <c:catch>.

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-9-

Ejemplo con core


* En este ejemplo se ve el uso de <c:set> (no olvidar la directiva
taglib:
<c:set var="aux" value="1" />
${aux}<br>
<c:set var="aux" value="${aux + 1}" />
${aux}<br>
<c:set var="cadena" value="mi nombre" />
${cadena}<br>
<c:set var="cadena" value="${cadena} es Sergio" />
${cadena}<br>

S
G
R

* Como puede verse, la concatenacin de cadenas se hace


mediante una mera yuxtaposicin.
* En este ejemplo se ve el uso de <c:catch>:
<c:catch var="fallo">
Esto sale bien<br>
<%
if (1==1)
throw new Exception("Fallo que se me ocurre");
%>
Esto ya no sale<br>
</c:catch>
${fallo}<br>
Continua la cosa bien<br>

* Si se quita la clusula <c:catch> se produce un fallo en la


pgina y no se carga nada.

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-10-

Etiquetas de control de flujo


* A menudo una pgina debe devolver al cliente diferentes
textos en funcin de los datos de entrada o almacenados en una
base de datos.
* Estas etiquetas evitan el tener que recurrir a Java directamente,
lo que suele ser propenso a errores debido al uso intensivo de
llaves.
* No tienen la misma potencia que las sentencias de control de
flujo en Java, sino que simulan bsicamente un if sin else y la
sentencia if en cascada.
* No existe nada parecido a un for, while o do while. Las
nicas sentencias de bucle que hay son las que permiten recorrer
estructuras y, por ello, estn ms asociadas al concepto de
iterador que al de control de flujo. Por esto no las veremos en
este apartado, sino ms adelante.

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-11-

<c:if>
* La sintaxis de <c:if> es:
<c:if
test=condicion
[var=nombreVar
[scope=page|request|session|application]]
>
// Acciones que se ejecutan si la condicion se cumple
</c:if>
* Si la etiqueta <c:if> se autocierra y se indica un nombre de
variable, entonces es como si se utilizara para cargar un valor
booleano en dicha variable.

S
G
R

* Como puede verse, esta etiqueta carece de clusula else. El


motivo es que la clusula else, utilizada a discrecin, se
convierte en unos ifs en cascada mutuamente excluyentes; y
para eso, la biblioteca core suministra otras etiquetas
* Ej. de control:

<c:if test="${ empty param.nombre}" >


Se le ha olvidado escribir un valor para el nombre.<br>
</c:if>

Puede probarse a cargar una pgina que contenga esto


psando o no pasando en la direccin URL el parmetro nombre.

* Ejemplo de carga de valor booleano:


<c:if var="existeNombre" test="${ empty param.nombre}" />
${existeNombre}<br>

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-12-

<c:choose>, <c:when> y
<c:otherwise>
* Estas tres etiquetas se emplean conjuntamente segn la
siguiente sintaxis
<c:choose>
<c:when test=condicion1>
// Cuerpo que se emite si condicion1 es cierta
</c:when>
<c:when test=condicion2>
// Cuerpo que se emite si condicion2 es cierta
// y condicion1 es falsa
</c:when>
....
<c:otherwise>
// Cuerpo que se emite si ninguna de las
// condiciones anteriores es cierta
</c:otherwise>
</c:choose>
* La estructura de estas etiquetas es la intuitiva: una vez entrado
en un <c:choose> se evalan los <c:when> en secuencia; en el
primero en que la condicin sea cierta, se emite su cuerpo y se
sale del <c:choose>. Si todas las condiciones son falsas se emite
el cuerpo de <c:otherwise>.

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-13-

Ejemplo con <c:choose>


* El siguiente ejemplo completo comprueba los parmetros de
entrada a un formulario y emite diferentes salida en base a estos:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<h3>Saludos</h3>
<c:choose>
<c:when test="${empty param.nombre}" >
Necesito un nombre.<br>
</c:when>
<c:when test="${empty param.tiempo}" >
Necesito un tiempo.<br>
</c:when>
<c:otherwise>
Hombre ${param.nombre}!.<br>
Cunto tiempo sin verte!<br>
Qu da ms ${param.tiempo} hace.<br>
</c:otherwise>
</c:choose>

S
G
R

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-14-

Etiquetas para recorridos


* Este tipo de etiquetas permite repetir la emisin de un trozo
JSP en base al nmero de elementos de una coleccin, array,
etc.
* Tambin se permite la iteracin sobre mapas y sobre
iteradores y enumeradores. Con estos ltimos hay que tener
cuidado ya que no se pueden resetear y no pueden recorrerse, a
su vez, varias veces.
* El recorrido puede ser sobre objetos o sobre tipos primitivos.
en este ltimo caso se hace una traduccin automtica al tipo
wrapper correspondiente.
* La iteracin tambin puede proporcionar un estado que puede
indicar, el nmero de componente por el que va el recorrido, etc.
Para ello se utiliza la clase LoopTagStatus.
* Tambin es posible realizar recorridos un nmero determinado
de veces, con variables lmite de inicio, final y paso.
* El desarrollador puede hacer uso de la clase LoopTag para
construir sus propias etiquetas que interaccionen con
<c:forEach>

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-15-

<c:forEach>
* La sintaxis es diferente segn se recorra una estructura o se
itere un determinado nmero de veces.
* La sintaxis que recorre una estructura es:
<c:forEach [var=nombreVar]
items=coleccion
[varStatus=nombreVarEstado]
[begin=comienzo]
[end=final]
[step=paso]
>
// Cuerpo a repetir
</c:forEach>

S
G
R

* Para ejecutarse un determinado nmero de veces, la sintaxis


es:
<c:forEach [var=nombreVar]
[varStatus=nombreVarEstado]
begin=comienzo
end=final
[step=paso]
>
// Cuerpo a repetir
</c:forEach>
* Ejemplo que saca los nmeros del 1 al 20:
<c:forEach var="cont" begin="1" end="20">
${cont}<br>
</c:forEach>

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-16-

<c:forEach>
* La sintaxis de la ejecucin un determinado nmero de veces
parece clara: la variable nombreVar parte del valor comienzo
hasta el valor final incrementndose en cada iteracin por paso
unidades.
* Si el recorrido de una coleccin hace uso de begin y dems,
quiere decir que se comienza en el tem de la coleccin situado
en posicin comienzo. Si hay menos tems que comienzo,
entonces el bucle ni se ejecuta. El primer elemento de la
coleccin est en la posicin 0.
* El <c:forEach> se usa para recorrer una coleccin de forma
que cada elemento visitado es apuntado por nombreVar
* Si la coleccin es un mapa, lo que se recorren son las entradas,
que son del tipo Map.Entry.
* Como coleccin tambin puede indicarse un array tradicional
e incluso un String. En este ltimo caso, se supone que el
String posee palabras separadas por comas, y el <c:forEach>
se ejecuta para cada una de tales palabras. La coma hace las
veces de carcter delimitador.
* Ejemplo de recorrido de los elementos de la cabecera
(header):
<c:forEach var="elemento" items="${header}">
${elemento}<br>
-> ${elemento.value}<br>
</c:forEach>

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-17-

<c:forTokens>
* El comportamiento de <c:forTokens> es muy parecido al de
<c:forEach> cuando se recorre un String. En el caso de
<c:forTokens> esposible indicar nuestros propios
delimitadores.
* La sintaxis de esta etiqueta es:
<c:forTokens items=cadenaDeTokens
delims=delimitadores
[var=nombreVar]
[varStatus=nombreVarEstado]
[begin=comienzo]
[end=final]
[step=paso]
>
// Cuerpo a repetir
</c:forEach>

S
G
R

* El funcionamiento de esto es como el de un StringTokenizer


que tiene como argumentos la cadenaDeTokens y los
delimitadores.
* Ntese la diferencia entre:
<c:forEach var="elemento" items="uno, dos, tres, cuatro,">
${elemento}<br>
</c:forEach>
Adios.<br>

y
<c:forTokens var="elem" items="uno,dos,tres,cuatro," delims=",o" >
${elem}<br>
</c:forTokens>
Adios.<br>
Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-18-

Transferencia de variables
* En el siguiente ejemplo se puede apreciar cmo intercambiar
informacin entre un scriptlet y el entorno JSP.
<%
int[] miLista = new int[]{1, 3, 5, 7, 11, 13, 17, 19, 23, 29};
pageContext.getSession().putValue("miArray", miLista);
%>
<c:forEach var="elemento" items="${miArray}" >
${elemento}<br>
</c:forEach>

* Las variables Java tambin se pueden cambiar desde JSP. En


el siguiente ejemplo se le pasa un valor a JSP desde un scriptlet.
Luego se cambia la variable en JSP y se recarga desde otro
scriptlet:
<h3>Saludos</h3>
<%
int miNumero = 234544;
pageContext.getSession().putValue("numero", miNumero);
%>
${numero}<br>
<c:set var="numero" value="16" scope="session" />
${numero}<br>
<%= miNumero %><br>
<%
miNumero =
Integer.parseInt(pageContext.getSession().
getValue("numero").toString());
%>
<%= miNumero %><br>
Adios.<br>

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-19-

Etiquetas para URLs


* Las diversas etiquetas suministradas permiten, entre otras
cosas:

Asignar un nombre a una URL para usarla varias veces en


la pgina JSP.

Asociar parmetros a una URL sin codificarlos en la


direccin en s.

Importar contenidos de cualquier URL de internet (y no


slo de recursos locales, como hace <jsp:include>).

Importar contenidos y meterlos en una variable String o


Reader, en lugar de emitirlos directamente.

Una URL puede ser absoluta, relativa, o relativa a un


contexto diferente del de la pgina en que est.

Redirigir la carga de la pgina a la URL que se indique.

S
G
R

* Las etiquetas disponibles son:


O <c:import> para disponer de contenidos de cualquier
lugar de internet, ya sea in line o metindolos en una
variable
O <c:url> permite hacer referencia a una URL y meterla
en una variable. Tambin permite indicar parmetros a la
URL de forma fcil
O <c:redirect> permite redirigir la carga de la pgina.
O <c:param> permite pasar parmetros a una URL sin
indicarlos directamente en la direccin.

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-20-

<c:url>
* Permite construir una URL completa rescribiendo las partes
que sean necesarias.
* La sintaxis de esta etiqueta es:
<c:url value=direccin
[context=contexto]
[var=nombreVar]
[scope=page|request|session|application]
>
<c:param ...>
<c:param ...>
</c:url>
* La direccion puede ser absoluta o relativa. Si es relativa se
rescribe para hacerla absoluta. Tambin puede ser relativa a un
contexto que no sea el de la pgina actual; en este caso el
sistema se encarga de rescribirla convenientemente.
* Si la direccion contiene caracteres raros, stos no son rescritos
por el sistema.
* Por defecto, la URL resultante es emitida (a travs del
JspWriter actual); pero en lugar de esto puede almacenarse en
una variable especificada en el atributo var.
* Pueden indicarse parmetros, que se aadirn a la URL
construida mediante la correspondiente recodificacin.

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-21-

<c:param>
* Permite aadir parmetros de forma indirecta a una URL.
* La sintaxis es:
<c:param
name=nombreParam
value=valorParam
/>
o bien, si el valor del parmetro es muy complicado:
<c:param
name=nombreParam >
valorParam
</c:param>

S
G
R

* Aunque hacer uso de esta etiqueta puede considerarse


redundante, ya que se puede escribir directamente en la URL,
hay que reconocer que el cdigo queda mucho ms claro.
Adems, este mtodo es consistente con el utilizado por
<jsp:include>, que tambin puede contener <jsp:param>.
* He aqu un ejemplo de uso:

<h3>Saludos</h3>
<c:url
value="http://www.google.es/search"
var="google"
>
<c:param name="hl" value="es" />
<c:param name="q" value="${param.consulta}" />
</c:url>
<a href="${google}">${google}</a><br>
Pincha <a href="${google}">aqu</a> para ir al mismo sitio.

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-22-

<c:import>
* Esta etiqueta se va a la URL especificada y: o la mete en lnea
donde se encuentra el <c:import>, o la mete en un objeto
Reader para que las acciones siguientes hagan lo que quieran
con el contenido.
* En el primer caso la sintaxis es:
<c:import
url=direccion
[context=contexto]
[var=nombreVar]
[scope=page|request|session|application]
[charEncoding=codificacion]
>
<c:param ...>
<c:param ...>
</c:import>
* Y en el segundo:
<c:import
url=direccion
[context=contexto]
varReader=nombreVarReader
[charEncoding=codificacion]
>
// Cuerpo en el que consumir desde nombreVarReader
</c:import>
* Con la segunda sintaxis no se aceptan parmetros porque se
confundiran con el cuerpo que consume el canal de entrada: no
se sabra cundo acaban los parmetros y cundo hay que abrir
el canal.
Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-23-

<c:redirect>
* La sintaxis es:
<c:redirect url=direccion
[context=contexto]
/>
* Tambin es posible indicar parmetros a esta URL, con lo que
la etiqueta <c:import> quedara abierta.
* Esta etiqueta cancela el procesamiento de la pgina y redirige
la carga hacia la URL indicada que:

Puede ser absoluta, relativa o relativa a un contexto. El


contexto, como en casos anterior, debe empezar por /.

Puede poseer parmetros de la forma <c:param>.


* Ejemplo de uso:

S
G
R

<h3>Saludos</h3>
<c:redirect url="StringBean.jsp" />

* Como puede observarse, el <c:redirect> puede usarse incluso


despus de haber emitido ya algo.

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-24-

Ejemplo de <c:import>
* El ejemplo que vimos de <c:out > y Reader se podra haber
hecho como:
<h3>Saludos</h3>
<c:import url="file:///e:/prueba.txt" />
Adis<br>

* Tambin el texto que se lee se puede meter en una variable de


mbito y leerlo lnea a lnea:
<h3>Saludos</h3>
<c:import url="file:///e:/prueba.txt"
var="lector"
/>
<c:forTokens var="elemento"
items="${lector}"
delims='<%="\n"%>'
>
${elemento} -</c:forTokens>
<br>
Adis<br>

* Tambin puede hacerse con un Reader:


<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@page import="java.io.*" %>
<h3>Saludos</h3>
<c:import url="file:///e:/prueba.txt" varReader="lector" >
<%
BufferedReader in = new BufferedReader(
(Reader)(pageContext.findAttribute("lector")));
String s;
while((s = in.readLine()) != null)
out.println(s+"<br>");
%>
</c:import>
Adios.<br>

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-25-

SQL Tag Library


* El prefijo estndar para esta biblioteca es sql. Para usarla hay
que incluir en la pgina JSP:
<%@ taglib uri="http://java.sun.com/jstl/sql" prefix="sql" %>

* Esta biblioteca permite:


T Ejecutar consultas con SELECT.
T Acceder fcilmente a los resultados de una consulta.
T Ejecutar actualizaciones con INSERT, UPDATE y
DELETE.
T Agrupar operaciones SQL en una transaccin.
T Cambiar rpidamente de base de datos.

S
G
R

* Las operaciones de esta biblioteca trabajan con objetos de tipo


DataSource que retorna uno de tipo Connection. El
DataSource sirve para hacer referencia a una base de datos en
concreto.
* El DataSource con que trabajar puede especificarse de varias
formas:

Directamente en el atributo dataSource de algunas


etiquetas, de dos formas:

dando directamente la informacin que necesita el


DriverManager: url [, driver] [, usuario, contrasea].
Ej.:
jdbc:pointbase:server://localhost:9092/sample,
com.pointbase.jdbc.jdbcUniversalDriver,pbPublic,pbPublic

dando un valor de JNDI que ser traducido por el


motor JNDI a la informacin necesaria de acceso a la
base de datos. Este mtodo tiene la ventaja de que
permite acceder a un pool de conexiones.
Como valor del atributo de configuracin:
javax.servlet.jsp.jstl.sql.dataSource

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-26-

<sql:setDataSource>
* Esta etiqueta permite especificar la fuente de datos de las
etiquetas sql que vendrn a continuacin. No obstante, no es
obligatorio especificarlo, puesto que la fuente de datos tambin
puede indicarse como atributo de un inicio de transaccin.
* La sintaxis es:
<sql:setDataSource
var=nombreVar
[scope=page|request|session|application]
[
dataSource=fuenteDeDatos
|
url=URL_JDBC
[driver=claseJavaDelDriver]
[user=nombreUsuario]
[password=contrasea]
]
/>
* El campo fuenteDeDatos, si se especifica, debe ser del tipo
javax.sql.DataSource.

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-27-

<sql:transaction>
* La sintaxis de esta etiqueta es:
<sql:transaction [dataSource=fuenteDeDatos]
[isolation= read_uncommited
|
read_commited
|
repeatable_read
|
serializable ]
>
// Cuerpo HTML que puede hacer uso de
// cuantas sentencias SQL se quiera
</sql:transaction>
* La transaccin ejecuta automticamente el COMMIT o el
ROLLBACK. El ROLLBACK lo ejecuta si captura alguna
excepcin en la ejecucin del cuerpo, y el COMMIT en caso
contrario.
* Cada tipo de aislamiento en la transaccin es ms potentes que
el anterior:

read_uncommited: lo lee todo, hasta lo que todava no se


le ha hecho un COMMIT.

read_uncommited: no hace lecturas sucias (datos a los


que no se ha hecho un COMMIT; pero s pueden suceder
relecturas ambiguas: una transaccin lee un registro, otra
transaccin modifica el registro, y la primera vuelve a leer
el registro otra vez, pero con un valor diferente!

repeatable_read: no hace relecturas ambiguas; pero s


pueden suceder lecturas fantasma: una transaccin lee
registros con WHERE, otra transaccin mete un nuevo
registro que satisface la condicin, y la primera vuelve a
leer los registros otra vez, pero con un nuevo registro
aparecido!

serializable: evita todos los problemas de inconsistencia.

S
G
R

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-28-

<sql:query>
* La sintaxis de esta etiqueta es:
<sql:query var=nombreVar
[scope=page|request|session|application]
[dataSource=fuenteDeDatos]
[startRow=numRegistroInicio]
[maxRows=numMaxRegistrosDevueltos]
>
// Sentencia SQL con el smbolo ? en el lugar
// de cada parmetro
<sql:param ...>
<sql:param ...>
</sql:query>
* Esta etiqueta permite ejecutar una sentencia select
parametrizada. Cada parmetro se identifica por un smbolo de
interrogacin ?. Las posteriores etiquetas <sql:param>
permiten sustituir cada uno de estos parmetros por un valor
real.
* La sentencia SELECT se ejecuta contra el DataSource
especificado en la etiqueta <sql:transaction> dentro de la que
se incluye, o bien contra el especificado en su atributo
dataSource.
* La variable indicada en el atributo var sirve para referenciar
el resultado que devuelve la sentencia SELECT ejecutada y
posee gran cantidad de campos.

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-29-

Lo que retorna <sql:query>


* El objeto retornado en var por <sql:query> pertenece a la
interfaz:
public interface Result {
public String[] getColumnNames();
public int getRowCount()
public Map[] getRows();
public Object[][] getRowsByIndex();
public boolean isLimitedByMaxRows();
}

S
G
R

* El siguiente ejemplo muestra cmo procesar un SELECT


simple:
<sql:transaction
dataSource="jdbc:pointbase:server://localhost:9092/sample,co
m.pointbase.jdbc.jdbcUniversalDriver,pbPublic,pbPublic" >
<sql:query var="clientes">
SELECT name FROM customer_tbl
</sql:query>
<c:forEach var="cliente" items="${clientes.rows}" >
${cliente.name}<br>
</c:forEach>
</sql:transaction>
----------<br>

* Es posible procesar un SELECT genrico haciendo uso de los


componentes de los mtodos de la interfaz Result.

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-30-

Recursos de Tomcat
* Para no tener que estar repitiendo constantemente en cada
pgina los datos de una DataSource, es posible especificar en
el fichero server.xml de Tomcat un recurso DataSource, darle
un nombre, y luego usarlo en las etiquetas JSTL por su nombre.
* De esta forma, cualquier modificacin a la cadena de conexin
queda centralizada en la declaracin de este recurso en
server.xml.
* Ejemplo:
<Context docBase="patata5" path="/patata5"
reloadable="true" debug="0">
<Resource
name="jdbc/orcl" auth="Container"
type="javax.sql.DataSource"
maxActive="100" maxIdle="3"
maxWait="10000" username="galvez"
password="alfa00"
driverClassName="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:@localhost:1521:orcl"/>
</Context>

que slo ser accesible a las pginas JSP del contexto


%TOMCAT_HOME%\webapps\patata5
* Una transaccin har uso de este recurso de la forma.
<sql:transaction dataSource="jdbc/orcl" >

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-31-

Uso de la interfaz Result


* El siguiente es un ejemplo completo de acceso genrico a
bases de datos:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>
<h3>Consulta genrica</h3>
<sql:transaction
dataSource="jdbc:pointbase:server://localhost:9092/sample,co
m.pointbase.jdbc.jdbcUniversalDriver,pbPublic,pbPublic" >
<sql:query var="clientes">
select * from customer_tbl
</sql:query>
<table border="1">
<tr>
<c:forEach var="nombreCampo"
items="${clientes.columnNames}" >
<th>${nombreCampo}</th>
</c:forEach>
</tr>
<c:forEach var="registro" items="${clientes.rowsByIndex}" >
<tr>
<c:forEach var="datoCampo" items="${registro}" >
<td>${datoCampo}</td>
</c:forEach>
</tr>
</c:forEach>
</table>
</sql:transaction>
----------<br>

S
G
R

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-32-

<sql:param> y
<sql:dateParam>
* Esta etiqueta sirve para pasar parmetros a sentencias SQL
preparadas. La sintaxis es:
<sql:paramvalue=valor />
o bien
<sql:param>
// valor del parmetro
</sql:param>
* Esta etiqueta sirve para sustituir los smbolos ? que se hayan
incluido en la sentencia SQL dentro de la cual se enmarca el
propio <sql:param>. Sirve para indicar parmetros de cualquier
tipo excepto fecha, para lo cual se usa la etiqueta
<sql:dateParam> cuya sintaxis es:
<sql:dateParam value=valorDeTipoDateDeJava
type=timestamp | time | date
/>
* Lo ms normal es que los parmetros de entrada a una pgina
JSP sean los que se utilicen para parametrizar una consulta SQL.
Estos parmetros entrada deberan validarse antes de enviarlos
a la consulta.

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-33-

Ejemplo de <sql:query>
* El siguiente es un ejemplo de pgina completa:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>
<h3>Consulta genrica</h3>
<c:choose>
<c:when test="${empty param.limite || empty param.hora}">
<form action="index.jsp" method="GET">
Lmite de crdito:
<input size=10 name="limite" value="0" /><br>
Hora a partir de la cual:
<input size=8 name="hora" value="0:0" /><br>
<input type=submit value="Buscar" />
</form>
</c:when>
<c:otherwise>
<% pageContext.setAttribute("horaDate",
new java.util.Date("1/1/1 "+ request.getParameter("hora")));
%>
<sql:transaction
dataSource="jdbc:pointbase:server://localhost:9092/sample,
com.pointbase.jdbc.jdbcUniversalDriver,pbPublic,pbPublic">
<sql:query var="clientes">
SELECT name, credit_limit, last_sale_time
FROM customer_tbl
WHERE credit_limit >= ? AND last_sale_time > ?
<sql:param value="${param.limite}" />
<sql:dateParam value="${horaDate}" type="time" />
</sql:query>
<table border="1">
<c:forEach var="cliente" items="${clientes.rows}" >
<tr>
<td>${cliente.name}</td>
<td>${cliente.credit_limit}</td>
<td>${cliente.last_sale_time}</td>
</tr>
</c:forEach>
</table>
</sql:transaction>
</c:otherwise>
</c:choose>

S
G
R

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-34-

<sql:update>
* Esta etiqueta permite ejecutar cualquier sentencia SQL que no
sea un SELECT. La sintaxis es:
<sql:update [var=nombreVar]
[scope=page|request|session|application]
[dataSource=fuenteDeDatos]
>
// Sentencia SQL de DDL o DML con el smbolo ?
// en el lugar de cada parmetro
<sql:param ...>
<sql:param ...>
</sql:update>
* La variable var hace referencia al nmero de elementos
afectados por la sentencia. Es de especial utilidad en sentencias
UPDATE y DELETE.
* Con esta etiqueta tambin pueden crearse tablas, borrarlas,
cambiarlas, crear restricciones, etc.
* Ejecutar <sql:update sql=rollback /> o <sql:update
sql=commit /> no est permitido y puede producir resultados
impredecibles.

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-35-

Ejemplo de <sql:update>
* El siguiente ejemplo crea una tabla, la rellena, la visualiza y
la borra:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>
<h3>Procesamiento</h3>
<sql:transaction
dataSource="jdbc:pointbase:server://localhost:9092/sample,
com.pointbase.jdbc.jdbcUniversalDriver,pbPublic,pbPublic" >
<sql:update>
CREATE TABLE a (campo1 NUMBER)
</sql:update>
<c:forEach var="contador" begin="1" end="20" step="3" >
<sql:update>
INSERT INTO a VALUES (?)
<sql:param value="${contador}" />
</sql:update>
</c:forEach>
<sql:query var="registros" >
SELECT campo1 FROM a
</sql:query>
<c:forEach var="registro" items="${registros.rows}">
${registro.campo1}<br>
</c:forEach>
<sql:update>
DROP TABLE a
</sql:update>
</sql:transaction>
----------<br>

S
G
R

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-36-

I18n Formatting Tag Library


* Esta biblioteca posee etiquetas que permiten formatear una
pgina en base a un idioma seleccionado posibilitando que sea
leda por personas de todo el mundo. El prefijo estndar para
esta biblioteca es fmt. Para usarla hay que incluir en la pgina
JSP:
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>

* Hace uso de los conceptos de internacionalizacin que ya se


han estudiado en captulos anteriores. Algunas etiquetas
interesantes son:
O <fmt:setLocale> especifica el Locale actual.
O <fmt:bundle> especifica el nombre base de los ficheros
de recursos.
O <fmt:message> emite el mensaje de cdigo
especificado en el idioma del Locale actual. El mensaje lo
busca en el fichero de recursos del bundle actual. Se le
pueden pasar parmetros.
O <fmt:requestEncoding> sirve para trabajar con
parmetros que proceden de un cdigo diferente al ISO8859-1.
* Nosotros nos vamos a centrar principalmente en las etiquetas
de formateo. <fmt:timeZone> y <fmt:setTimeZone> no las
veremos.

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-37-

<fmt:formatNumber> y
<fmt:parseNumber>
* Estas etiquetas permiten emitir un nmero que siga el formato
que se le indice, as como traducir un texto a un nmero
siguiendo un patrn concreto de anlisis. Las sintaxis son:
<fmt:formatNumber
value=valorNumrico
[var=nombreVar]
[scope=page|request|session|application]
[type=number | currency | percent ]
[pattern=patronPersonalizado]
[currencyCode=codigoDeMoneda]
[currencySymbol=simboloDeMoneda]
[groupingUsed=true | false ]
[maxIntegerDigits=maximoNumeroDeDigitos]
[minIntegerDigits=minimoNumeroDeDigitos]
[maxFractionDigits=maximoNumeroDeDecimales]
[minFractionDigits=minimoNumeroDeDecimales]
/>
y
<fmt:parseNumber
value=valorNumricoEnUnaCadena
[var=nombreVar]
[scope=page|request|session|application]
[type=number | currency | percent ]
[pattern=patronPersonalizado]
[parseLocale=LocaleDelParser]
[integerOnly=true | false]
/>

S
G
R

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-38-

<fmt:formatNumber> y
<fmt:parseNumber>
* El patrn de formateo debe seguir las reglas de la clase
java.text.DecimalFormat.
* El atributo groupingUsed permite decir si se va ausar algn
carcter de agrupacin. Ver java.text.NumberFormat.
setGroupingUsed() para ms informacin.
* El atributo parseLocale sirve para decir el Locale en base al
cual hay que hacer el anlisis del nmero almacenado en la
cadena de entrada.
* El atributo integerOnly especifica que slo debe reconocerse
la parte entera del nmero guardado en la cadena.
* Por ejemplo, el formateo :
<fmt:formatNumber
value="${100000000 / 3}"
type="currency"
currencySymbol=""
groupingUsed="true"
maxIntegerDigits="4"
maxFractionDigits="2"
minFractionDigits="2"
/>

produce:
3.333,33
as que cuidado con maxIntegerDigits, ya que el resultado
debiera haber sido:
33.333.333,33
Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-39-

<fmt:formatDate> y
<fmt:parseDate>
* Estas etiquetas permiten trabajar con fechas. Las sintaxis son:
<fmt:formatDate
value=valorDeFecha
[var=nombreVar]
[scope=page|request|session|application]
[type=date | time | both]
[pattern=patronPersonalizado]
[dateStyle=default | long | medium | short | full]
[timeStyle=default | long | medium | short | full]
[timeZone=zonaTemporal]
/>
y
<fmt:parseDate
value=valorFechaEnUnaCadena
[var=nombreVar]
[scope=page|request|session|application]
[type=date | time | both]
[pattern=patronPersonalizado]
[dateStyle=default | long | medium | short | full]
[timeStyle=default | long | medium | short | full]
[timeZone=zonaTemporal]
[parseLocale=LocaleDelParser]

S
G
R

/>
* dateStyle y timeStyle
java.text.DateFormat.
Captulo 18: JSTL (Java Standard Tag Library).

siguien

el

formateo

de

Programacin en Java. Universidad de Mlaga, 2006.

-40-

<fmt:formatDate> y
<fmt:parseDate>
* Algunos ejemplos de funcionamiento son:
<jsp:useBean id="ahora" class="java.util.Date" />
<fmt:formatDate value="${ahora}" /><br>
<fmt:formatDate value="${ahora}" type="both" /><br>
<fmt:formatDate value="${ahora}" type="time" /><br>
<fmt:formatDate value="${ahora}"
type="time" timeStyle="short" /><br>
<fmt:formatDate value="${ahora}"
pattern="dd/MM/yyyy" /><br>

cuya salida es:


30-ene-2006
30-ene-2006 20:46:56
20:46:56
20:46
30/01/2006

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-41-

I18n Formatting Tag Library


* El lenguaje de expresiones define el concepto de funciones
para permitir a los desarrolladores crear sus propias extensiones
a este lenguaje. El prefijo estndar para esta biblioteca es fn.
Para usarla hay que incluir en la pgina JSP:
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>

* Esto no son etiquetas realmente, sino funciones con prefijo


que pueden usarse en el interior de una expresin del lenguaje
de expresiones.

S
G
R

* Las funciones son las siguientes:

De bsqueda en cadenas:
Ofn:contains(string, substring) devuelve boolean
Ofn:containsIgnoreCase(string, substring) devuelve
boolean
Ofn:endsWith(string, sufijo) devuelve boolean
Ofn:startsWith(string, prefijo) devuelve boolean
Ofn:indexOf(string, substring) devuelve int. La primera
posicin de string es la 0. Si no est se devuelve -1.
De obtencin de subcadenas:
Ofn:substring(string, beginIndex, endIndex) devuelve
String. Las posiciones comienzan a partir de la 0. El
carcter en beginIndex se incluye y el de enIndex se
excluye.
Ofn:substringAfter(string, substring) devuelve String
Ofn:substringBefore(string, substring) devuelve String

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-42-

Funciones (cont.)
Traduccin de cadenas:
Ofn:replace(inputString, beforeSubstring, afterSubstring)
devuelve String
Ofn:toLowerCase(string) devuelve String
Ofn:toUpperCase(string) devuelve String
Ofn:trim(string) devuelve String. Elimina los espacios a
ambos extremos de la cadena.
Gestin de arrays y cadenas:
Ofn:join(array, separador) devuelve String. Convierte un
array en una cadena. Cada dos elementos estn separados
por la cadena separador.
Ofn:split(string, delimitadores) devuelve String[]. Trocea
una cadena en un array de cadenas. Los trozos estaban
originalmente separados por cualquier carcter de los que
aparece en delimitadores.
Ofn:length(input) devuelve integer. La entrada puede ser
una cadena o un array o una coleccin y devuelve su
longitud o el nmero de elementos respectivamente.
Otras:
Ofn:escapeXml(string) devuelve String. Vase el atributo
escapeXml de <c:out>.

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-43-

Ejemplos de funciones
* Algunos ejemplos son:
<%-- Trunca el nombre a 30 caracteres y lo visualiza en
maysculas --%>
${fn:toUpperCase(fn:substring(nombre, 0, 30))}
<%-- Visualiza el texto que precede al primer asterisco --%>
${fn:substringBefore(texto, *)}
<%-- La variable custId puede tener espacios en blanco en los
extremos. Esto los quita --%>
<c:url var="myUrl" value="${base}/cust">
<c:param nombre="custId" value="${fn:trim(custId)}"/>
</c:url>
<%-- Visualiza el texto entre parntesis --%>
${fn:substring(text, fn:indexOf(texto, ()+1,fn:indexOf(texto, )))}
<%-- Visualiza el nombre si contiene la cadena a buscar --%>
<c:if test="${fn:containsIgnoreCase(nombre, searchString)}">
Encontrado en el nombre: ${nombre}
</c:if>
<%-- Visualiza los ltimos 10 caracteres --%>
${fn:substring(text, fn:length(texto)-10)}
<%-- Visualiza un valor con bolillas en vez de guiones --%>
${fn:replace(texto, -, &#149;)}

S
G
R

Captulo 18: JSTL (Java Standard Tag Library).

Programacin en Java. Universidad de Mlaga, 2006.

-44-

XML Tag Library


* Esta biblioteca posee etiquetas que permiten analizar, procesar
y buscar informacin dentro de un documento XML. El prefijo
estndar para esta biblioteca es x. Para usarla hay que incluir en
la pgina JSP:
<%@ taglib uri="http://java.sun.com/jsp/jstl/xml" prefix="xml" %>

* No entraremos en detalle en sus etiquetas. Baste decir que son:


O <x:parse> que analiza un documento XML y puede
devolver un org.w3c.dom.Document.
O <x:out> que evala una expresin Xpath y emite el
resultado.
O <x:set> igual al anterior pero guarda el resultado en una
variable.
O <x:if>, <x:choose>, <x:when>, <x:otherwise> y
<x:forEach> para recorrer contenidos basados en
expresiones Xpath.
O <x:transform> y <x:param> para aplicar hojas XSLT
a un documento XML.

Captulo 18: JSTL (Java Standard Tag Library).

También podría gustarte