Está en la página 1de 42

Enlaces relacionados con

Programando este tutorial


Curso servidores
Página personal J. J. Merelo
con JSPs
AQUI

1 Introducción: servidores y
contenedores de servlets/JSPs
Los servlets y Java Server Pages (JSPs) son dos
métodos de creación de páginas web dinámicas en
servidor usando el lenguaje Java. En ese sentido son
similares a otros métodos o lenguajes tales como el
PHP, los CGIs (common gateway interface), programas
que generan páginas web en el servidor, o los ASP
(Active Server Pages), un método específico de
Microsoft. Sin embargo, se diferencian de ellos en otras
cosas.

Para empezar, los JSPs y servlets se ejecutan en


una máquina virtual Java, lo cual permite que, en
principio, se puedan usar en cualquier tipo de
ordenador, siempre que exista una máquina virtual
Java para él. Cada servlet (o JSP, a partir de ahora lo
usaremos de forma indistinta) se ejecuta en su propia
hebra, es decir, en su propio contexto; pero no se
comienza a ejecutar cada vez que recibe una petición,
sino que persiste de una petición a la siguiente, de
forma que no se pierde tiempo en invocarlo (cargar
programa + intérprete). Su persistencia le permite
también hacer una serie de cosas de forma más
eficiente: conexión a bases de datos y manejo de
sesiones, por ejemplo.

Los JSPs son en realidad servlets: un JSP se


compila a un programa en Java la primera vez que se
invoca, y del programa en Java se crea una clase que
se empieza a ejecutar en el servidor como un servlet.
La principal diferencia entre los servlets y los JSPs es el
enfoque de la programación: un JSP es una página
Web con etiquetas especiales y código Java incrustado,
mientras que un servlet es un programa que recibe
peticiones y genera a partir de ellas una página web

ACA

Ambos necesitan un programa que los contenga, y


sea el que envíe efectivamente páginas web al
servidor, y reciba las peticiones, las distribuya entre los
servlets, y lleve a cabo todas las tareas de gestión
propias de un servidor web. Mientras que servidores
como el Apache están especialmente pensados para
páginas web estáticas CGIs, y programas ejecutados
por el servidor, tales como el PHP, hay otros servidores
específicos para servlets y JSPs llamados contenedores
de servlets (servlet containers) o servlet engines. Los
principales son los siguientes:

 Resin, de Caucho Technologies, un motor


especialmente enfocado al servicio de páginas
XML, con una licencia libre para desarrolladores.
Dice ser bastante rápido. Incluye soporte para
Javascript además de Java. Incluye también un
lenguaje de templates llamado XTP. Es bastante
fácil de instalar, y en dos minutos, se pueden
empezar a servir páginas JSP.
 BEA Weblogic es un servidor de aplicaciones de
alto nivel, y también de alto precio. Está escrito
íntegramente en Java, y se combina con otra serie
de productos, tales como Tuxedo, un servidor de
bases de datos para XML.
 JRun, de Macromedia, un servidor de aplicaciones
de Java, de precio medio y probablemente
prestaciones medias. Se puede bajar una versión
de evaluación gratuita
 Lutris Enhydra, otro servidor gratuito y Open
Source, aunque tiene una versión de pago.
También enfocado a servir XML, y para
plataformas móviles. Las versiones más
actualizadas son de pago, como es natural
 El más popular, Open Source, y continuamente en
desarrollo, es el Jakarta Tomcat, del consorcio
Apache, un contenedor de servlets con muchos
desarrollos adicionales alrededor; por ejemplo,
Cocoon para servir páginas XML. Puede servir
páginas sólo o bien como un añadido al servidor
Apache. Es Open Source, relativamente rápido, y
fácil de instalar. La versión actual es la 4.0.3,
aunque siguen saliendo versiones de la 3.

Otros muchos se pueden encontrar en la


página de Sun sobre la industria del servlet/JSP y
en la página de contenedores de servlets en
servlets.com

Contenido de esta sección


 Prerrequisitos
para instalar un
servidor
 Instalando un
contenedor de
servlets
Ejecutando los
2 Instalando 
primeros JSPs
un  Hosting de
servlets, de
contenedor pago y gratuito

de servlets
Vamos a ver cómo se instala un contenedor
de servlets. Nos fijaremos especialmente en la
versión 4.0 de Tomcat, aunque lo que se cuente
valdrá para casi todos los otros contenedores
Open Source. Los de pago, probablemente
tendrán un interfaz pijo para instalarlos, a base
de botoncitos, o si son los muy caros, vendrá un
señor con corbata y maletín de cuero para
hacerlo, así que de esos no nos preocuparemos
demasiado.

Antes siquiera de bajarse el programa en


cuestión, hay que considerar previamente de la
máquina virtual Java que vamos a usar para
ejecutarlo. Todos están escritos en Java, así que
esto es esencial. Principalmente, hay dos
opciones: las JVM de Sun (que son las originales)
o las de IBM, que son algo más rápidas, pero que
no siempre están actualizadas hasta la última
versión. Un contenedor de servlets necesita el
JDK completo, no sólo el runtime environmnt,
principalmente por el compilador de java
contenido en un fichero llamado tools.jar. En
cualquier caso, nos podemos bajar la JVM de Sun
en sus versiones para Linux, o para cualquier otra
plataforma (en la versión 1.4), o bien la versión
1.3 de IBM (la más aconsejable). Si no se
consigue una versión de esas, es aconsejable
conseguir una que sea compatible con la versión
"2" de Java, es decir, JVMs a partir de la versión
1.2. Puede que funcionen con versiones
anteriores, pero lo más probable es que no lo
hagan.

Igual está ya Java instalado en el sistema;


habrá que verificar que java y tools.jar están
también instalados; basta con intentar ejecutarlo,
o bien preguntarle al administrador del sistema,
que también es una criaturita del señó y tiene
derecho a que alguien le dirija la palabra, caray.

Una vez instalada la JVM, nos bajamos el


servidor de su sitio correspondiente (
http://jakarta.apache.org/builds/jakarta-tomcat-
4.0/release/), si puede ser, en versión binaria, ya
compilada. Si disponemos de una distro de Linux
que use el RPM para instalación de paquetes
(como Mandrake, RedHat o SuSE), se puede uno
bajar los RPMs e instalarlos directamente.
Dependiendo de lo que elijamos, habrá que
bajarse sólo un paquete, o bien varios. En todo
caso, habrá que incluir lo siguiente: Xerces-J,
regexp, servletapi, tomcat y tomcat-webapps. Si
bajamos el fichero .tar.gz, viene todo incluido.
Para instalar el RPM se hace lo siguiente:

[yo@mimaquina]$ rpm -Uvh tomcat4-4.0.2-


3.noarch.rpm

(esto después de haber instalado todos los


paquetes previos. Si se ha bajado el tar:

[yo@mimaquina]$ tar xvfz tomcat4-4.0.2.tar.gz

Ya desempaquetado, tendremos el Tomcat


listo para funcionar. Dependiendo de la manera
de descargargarlo, tendremos el servidor en un
directorio u otro, pero siempre habrá directorios
conf, lib, bin y webapps. A continuación, habrá que
decirle dónde se encuentra la máquina virtual
Java, editando un fichero tomcat.conf que se
encuentra dentro del directorio conf (que variará
de sitio según la distribución; puede ser en
/etc/tomcat4/conf o en directorio_del_tomcat/conf). En
otros sistemas operativos, o con otro tipo de
instalación, habrá que definir una variable de
entorno, de esta forma:

[yo@mimaquina]$ export JAVA_HOME=/opt/IBMJava2-13

o bien

[yo@mimaquina]$ setenv JAVA_HOME /opt/IBMJava2-13

, dependiendo de si se trata del intérprete de


comandos bash (el primero) o *csh (el segundo). En
WinXX habrá que dar una orden similar.
Finalmente para ejecutar el servidor, fijándonos
en el caso de haberlo instalado usando el RPM,
hacemos:

[yo@mimaquina yo]$ /etc/rc.d/init.d/tomcat4 start

En otros casos, habrá que ir al directorio


bin de la distribución y ejecutar ./startup.sh o
startup si se trata de Windows. Si todo falla,
siempre se puede mirar el manual. Por defecto, el
servidor viene configurado para lanzarse en el
puerto 8080 u 8180 (dependiendo de las
versiones). Si todo ha ido bien, tendremos
funcionando en nuestro ordenador al Tomcat, y al
introducir una dirección tal como
http://localhost:8080 o http://localhost:8180 (si
quieres usar direcciones por debajo de 1000
tendrás que ser superusuario).

Si no te sale lo anterior, puede ser por miles


de razones diferentes. La primera es comprobar
que efectivamente el servidor está funcionando. El
principal problema de Tomcat es que falla
silenciosamente: ejecuta cosas, y parece que ha
arrancado, pero, sin embargo, no lo ha hecho.
Para ver si está funcionando tienes diferentes
opciones: usar netstat para ver si el puerto está
ocupado y alguien está escuchando en él (y si es
el Tomcat, mejor; si no lo es, ha fallado por eso,
porque no ha podido ocupar el puerto), escuchar
atentamente el disco duro a ver si al arrancar el
tomcat le ha dado vidilla, lo cual indica que
efectivamente está funcionando; mirar a ver si
hay algo en el directorio webapps , porque si no lo
hay, va a dar un fallo de contexto o algo por el
estilo, con lo fácil que es decir, joer, que no hay
una puñetera página, ¡caray!. También es
interesante tratar de ejecutar los ejemplos: si
fallan los JSPs pero no los servlets, es que no se
ha encontrado el fichero tools.jar, que, a pesar de
su nombre, es el que compila los JSPs. Por último,
hay que mirar en el registro de catalina, en
log/catalina_log.[fecha].txt; si se ha arrancado
correctamente, aparecerá algo así:

2002-03-11 08:33:13 HttpConnector Abriendo


sockets de servidor en todas las
direcciones IP disponibles
2002-03-11 08:33:15 HttpConnector[10001]
Iniciando thread de posterior
2002-03-11 08:33:15
HttpProcessor[10001][0] Iniciando thread
de posterior

Si solamente pone el primer mensaje,


chungo; no ha iniciado ninguna hebra, que son las
que efectivamente sirven los JSPs. Si no es nada
de eso, mira los mensajes de error en el
subdirectorio log, a veces indican que falta algun
fichero, o bien que hay un problema de versiones
de la máquina virtual Java.
Una vez que se ha instalado, y se ha
comprobado que funciona correctamente, se
puede intentar cambiar la configuración, sobre
todo teniendo en cuenta el número de visitas
esperadas. La mayoría de los cambios de
configuración se hacen sobre el fichero
conf/server.xml. Para cambiar el puerto en el que se
escucha y el número de servidores disponibles
mínimo y máximo, hay que cambiar la siguiente
orden:

<Connector
className="org.apache.catalina.connector.h
ttp.HttpConnector"

port="10001"minProcessors="2"
maxProcessors=" 5"
enableLookups="true"
redirectPort="8543"
acceptCount="10" debug="0"
connectionTimeout="60000"/>

La configuración de Tomcat se hace sobre un


fichero que usa el lenguaje XML. Con él, se
definen una serie de elementos: servidores,
conectores y contenedores; la configuración se ha
simplificado mucho desde la versión anterior,
aunque introduce nuevos elementos: las válvulas
y los motores. Tomcat define para cada servidor
una serie de conectores, mediante los cuales
diferentes clases responden a diferentes puertos,
y se encargan de servirlos; los contenedores o
motores se encuentran dentro de los conectores,
y se encargan de manejar todas las peticiones
para un servicio. Salvo que se vayan a usar
aplicaciones particulares (tales como Cocoon), no
hay que preocuparse mucho del tema. En nuestor
caso, sólo habrá que cambiar el número mínimo
de procesadores (o hebras que sirven peticiones)
y el máximo, para no sobrecargar demasiado el
sistema en caso de que se cuente con poca
memoria principal. El mínimo aceptable es 2, y el
máximo es hasta 65535 o hasta que la memoria
aguante (que no aguantará mucho). En cuanto al
puerto, se puede usar cualquiera, siempre que no
esté ya usado, y siempre que se ejecute desde
superusuario; si no se es superusuario, hay que
usar los puertos por encima del mil. Una vez
hecho esto, hay que rearrancar el servidor para
que tome los nuevos cambios:

[yo@mimaquina yo]$ /etc/rc.d/init.d/tomcat4


restart

Para ahorrar recursos, se pueden eliminar


cosas de ese fichero. Por ejemplo, si se trata de
un servidor de desarrollo, no necesitamos
conectores para el apache ni conexiones que usen
SSL. Se puede eliminar la el servicio Tomcat-
Apache, eliminando todo lo comprendido entre la
etiqueta Service y su contraetiqueta. También se
pueden eliminar los conectores AJP, SSL,
"proxied", y de test, indicados con un comentario,
justo debajo del conector normal (el non-SSL
HTTP/1.1 ). Se pueden ahorrar unos pocos más
recursos iniciando la JVM de forma que se limite el
tamaño del heap y de la pila, pero no se ahorra
demasiado espacio. Un Tomcat funcionando no
ocupará nunca menos de 90 megas (lo que se
puede ver ejecutando el top o gtop o bien, desde la
línea de comandos, ps -exfua.

También se puede añadir un nuevo contexto


al servidor; sobre todo si queremos que nuestras
aplicaciones no se mezclen con el resto de las
aplicaciones en el contexto raíz (las contenidas en
el directorio ROOT. Para ello, se puede añadir, justo
después de la línea donde se define tal contexto,
lo siguiente:
<Context path="/micontexto" docBase="micontexto" debug="0"/>

(substituyendo micontexto por el valor


adecuado; ambos nombres no tienen porqué ser
iguales). El path indica el URI que se va a utilizar
para referirse a él cuando lo llamen desde algún
navegador, es decir, http://miservidor/micontexto, y
el segundo nombre es el subdirectorio del
directorio webapps al que se refiere

Una vez realizada la aplicación, se puede


alojar en un servidor que ofrezca este servicio.
Por ejemplo, Verio ofrece soluciones basadas en
el sistema operativo Solaris (el precio hay que
consultarlo). Un revendedor de este servicio,
SoyDigital, menciona precios a partir de 210 €.

También hay alternativas gratuitas, aunque


no son eternas como en el caso de GeoCities. Una
de ellas es iSavvix DevSpace, que permite
alojamiento gratuito de JSPs, con librerías de tags
e incluso XSLT; lo que no permite, es que uno
suba sus propias clases, aunque se pueden usar
diversas librerías de clases presentes en el sitio.
Otra alternativa, WebAppCabaret, que da diversos
contenedores de servlets como alternativa:
Tomcat y NGASI, Enterprise Java Beans, bases de
datos con MySQL, pero todo ello por solamente 15
días; más allá de eso, hay que contratar el
servicio Premium, a partir de 3$. Por último,
MyCGIserver también permite alojamiento
gratuito; hay que responder a una pregunta
relacionada con los servlets, pero es usualmente
fácil de encontrar la respuesta.

Ejercicios 1
1. Seguir los pasos anteriores e instalar un
contenedor de servlets en el ordenador.
Probar con el Tomcat, y si todo va bien,
probar también con el Caucho Resin. El
proceso es bastante similar. Cambiar la
configuración de Tomcat de forma que
cada conector use sólo 2 hebras mínimo, y
5 máximo. Cambiar al puerto al 10001;
rearrancar el servidor. Definir un nuevo
contexto para los ficheros propios.
2. Darse de alta en algún servidor gratuito,
y subir alguno de los ejemplos de Resin o
de Tomcat para probarlo.

3 Nuestra Contenido de esta sección


 Cómo
primera página crear y
dónde
JSP poner la
página
Si todo va bien, y  hola.jsp
los ejemplos se ejecutan
correctamente, ya está
uno listo para crear su primer programa, o
página, en JSP (depende de como uno lo mire).
Como las páginas JSP son básicamente páginas
HTML con un poco de Java por medio, sirven, en
principio, cualquier editor que comprenda la
sintaxis HTML y/o XML; por ejemplo, el XEmacs.
Algunos otros entornos, tales como el Sun ONE,
una plataforma de desarrollo completa (que
consume un montón de recursos), el Visual Age
for Java; estos dos están escritos en Java y
pueden ejecutarse en cualquier plataforma. El
Dreanweaver Ultradev, sin embargo, existe sólo
en versión Windows. Forté es gratuito, y los otros
dos son de pago, aunque hay versiones de prueba
de tiempo limitado que se pueden bajar.

Con cualquier editor de texto se puede crear


la primera página JSP (hola.jsp; en acción en
iSavvix):
<!-- (c) JJ -->
<%@ page language='java'
contentType="text/html" %>
<%! int count=0; %>
<html>
<head><title>Hola y números. Intro to
JSP</title></head>
<body bgcolor="white">
Hola, mundo. Te lo repito <%= count++ %>
<% if (count == 1) { %>
vez
<% } else { %>
veces
<% } %>
</body></html>

Tras editar esa página, habrá


que ponerla en algún sitio. La
estructura de directorios de Tomcat
(y de otros contenedores de
servlets) es un poco más compleja
que la de los servidores web
normales. Todos los ficheros cuelgan del
directorio webapps, pero no se pueden colocar
directamente ahí. De ese directorio descienden
otros subdirectorios, que es donde efectivamente
se colocan las aplicaciones. Cada directorio
corresponde a un contexto; hay un contexto raíz
ROOT y tantos otros contextos como queramos
definir. Dentro de cada contexto, la estructura de
directorios es también siempre la misma;
directamente descendiendo del directorio se
pueden poner los JSPs, y hay también un
directorio WEB-INF donde hay una serie de ficheros
de configuración y propiedades, y además otros
directorios: classes y lib (que no aparece en esta
imagen). En esos directorios se pondrán más
adelante los ficheros .class y .jar,
respectivamente. Por tanto, el fichero anterior, irá
a parar al directorio ROOT (o bien al directorio del
contexto propio que hayamos definido en el
ejercicio anterior). También se puede colocar en
cualquiera de los subdirectorios del directorio
webapps, pero no en el principal

El fichero contiene la mayoría de los


elementos de un JSP. Para empezar, la línea 2 <%@
page language='java' contentType="text/html" %> incluye
una directiva, que son órdenes que se ejecutan
antes de que se comience a procesar el JSP, y
modifican de alguna forma el resultado del
mismo. Todas las directivas en JSP se indican con
una @ después del comienzo de la orden JSP (<%).
En este caso, le indicamos que la página que se
va a ejecutar está en lenguaje Java, y que el
contenido que va a generar es de tipo text/html; el
estándar JSP, a pesar de su nombre, no está
limitado a un solo lenguaje, aunque en la práctica
se usa casi siempre Java, y en algunos casos
JavaScript. En cuanto al contenido, JSP trabaja,
por defecto, con HTML, pero se podrían generar
páginas en otros estándares tales como el WML
que se usa en los móviles WAP, o XML.

La directiva page puede incluir otros atributos:

<%@ page language='java'


contentType="text/html"
info='Mi primera página en JSP"
import='java.util.*'
errorPage='errorQueTeCagas.jsp' %>

info es una especie de comentario, que usa el


contenedor para describir la clase en su interfaz
de administración; import permite especificar una
serie de paquetes en Java para importar, y
errorPage indica la página a la que habría que saltar
en caso de que se genere una excepción. Ahora
mismo, ninguno de estos atributos son
necesarios, y, de hecho, la página funciona
perfectamente bien sin ellos; en ese caso, tomaría
los valores por defecto, es decir, lenguaje HTML
para la página y Java para los scriptlets.

Justo a continuación, la línea <%! int count=1;


%> es una declaración; la admiración (!) se usa
para indicar declaraciones de variables globales,
es decir, variables persistentes de una llamada a
otra del JSP; y es compartida por todas las
llamadas a una página. La declaración se
ejecutará la primera vez que se llame a la página,
y se volverá a ejecutar cada vez que se recompile
la página (o se rearranque el servidor); el efecto
que tendrá esta declaració será un contador de
visitas, que se incrementará cada vez que se
visite. Por lo demás, la declaración es una
declaración normal en Java; se pueden incluir
tantas declaraciones como se quieran, no
necesariamente al principio de la página.

A continuación vienen una serie de elementos


HTML, hasta la línea 7, donde se encuentra la
orden <%= count++ %>. Todo lo que comience por <%=
es una expresión JSP; el efecto que tiene es la
evaluación de la expresión y la impresión del
resultado. En este caso, se ejecuta la expresión y
luego se imprime el valor, que es lo que hace el
operador post-incremento ++. Las expresiones en
JSP pueden contener sólo expresiones Java que
devuelvan un valor, y no hace falta que se
terminen con ;, como en el caso de las
declaraciones.

A continuación se encuentra una combinación


de código Java y elementos de texto que se suele
denominar scriptlet. Los scriptlets usan la sintaxis
JSP normal, <% y %>; y dentro, se puede incluir
cualquier cacho de programa en Java que se
quiera. En este caso es una sentencia if, y lo
único relevante es que el código Java está
mezclado con el texto; en este caso, se incluiría
condicionalmente un texto u otro en la página de
salida. Se podría hacer usando sólo Java, de esta
forma

<% if (count == 2)
System.out.println('vez')
} else {
System.out.println('veces')
} %>

Sin embargo, de esta forma, se pueden


incluir más fácilmente todo tipo de estructuras
HTML, sin necesidad de meter montones de
System.out. Lo del count == 2 es porque, cuando llega
ahí el programa la primera vez que se ejecuta, el
contador ya vale dos, porque se ha incrementado
en la línea anterior.

Si no queremos tomarnos toda la molestia de


meterlo en el contnedor de servlets, podemos
intentar compilarlo antes, para ver si hay algún
errorcillo que se nos hubiera saltado, por ejemplo
de sintaxis. Se puede usar para ello el compilador
de JSPs offline; Tomcat incluye jasper, que se
puede usar de la forma siguiente (versión 4):

djasper4 jspc hola.jsp

(aunque en el RPM de la versión 4.0.2 no


funciona correctamente, creo...). Si todo va bien,
se genera un fichero hola.java que, sería el que,
compilado, daría el servlet; de hecho, este fichero
se podría compilar y ponerse como servlet. Esta
compilación no es necesaria, pero si estamos
trabajando con un fichero grande y no tenemos
muy claro si la sintaxis es correcta, se puede
usar; aunque en la mayor parte de los casos, se
lo tragará todo y dejará al engine el coger los
errores. De hecho, no he conseguido que dé un
error, por muchas cosas que le he he hecho...

Si nos hemos equivocado en alguna cosa, el


contenedor de servlets dará los errores
correspondientes. Por ejemplo, si alguna etiqueta
de JSP no la hemos puesto bien (< } %>), saldrá
algo así:

org.apache.jasper.JasperException: No se
puede compilar la clase para JSP
/var/tomcat4/work/localhost/jmerelo/hola$j
sp.java:90: 'catch' without 'try'.
} catch (Throwable t) {
^

/var/tomcat4/work/localhost/jmerelo/hola$j
sp.java:98: 'try' without 'catch' or
'finally'.
}
^

/var/tomcat4/work/localhost/jmerelo/hola$j
sp.java:98: '}' expected.
}
^
3 errors

tras explicar el tipo, el mensaje y la


descripción. En realidad, este mensaje no tiene
nada que ver con el error, pero es lo más que se
puede pedir, teniendo en cuenta que tenemos
varias fases de compilación. A lo que hay que
prestarle atención es a la última línea, la que dice
que se esperaba un }; como el cierre de llave está
fuera de una etiqueta JSP, el intérprete no lo
entiende. Sin embargo, si cometemos un error de
sintaxis Java, la cosa estará un poco más clara:
org.apache.jasper.JasperException: No se
puede compilar la clase para JSP

An error occurred at line: 10 in the jsp


file: /hola.jsp

Generated servlet error:


/var/tomcat4/work/localhost/jmerelo/hola$j
sp.java:83: Invalid expression statement.
} ese {
^

An error occurred at line: 10 in the jsp


file: /hola.jsp

Generated servlet error:


/var/tomcat4/work/localhost/jmerelo/hola$j
sp.java:83: ';' expected.
} ese {

Como los errores no son muy informativos,


muchas veces no queda otro remedio que leer
bien leido el código de error, y mirar las fuentes,
a ver qué es lo que le ha molestado. En estas
cosas, como en otras muchas, la experiencia es
un grado.

Ejercicios 2
1. Usando la clase java.util.Date, hacer un
JSP que imprima la hora y los minutos, y
probarlo en algún servidor gratuito o en un
servidor propio

4 Elementos Contenido de esta sección


 Etiquetas
adicionales del jsp
 Clases en
JSP. Beans. Java. Beans

A partir de este
momento, vamos a intentar montar paso a paso
una quiniela en Internet, que la gente pueda
rellenar, votar los resultados, y, finalmente, sacar
un resumen de todos para que en la oficina se
rellene la quiniela común de acuerdo con ello
(aunque siempre hay un asaúra que está en
desacuerdo, y que quiere ponerle un 2 al Depor-
Recre).

Para empezar, vamos a montar simplemente


un JSP que presente el resultado de un partido,
un resultado que incluiremos también dentro de la
página (resultado0.jsp; y en acción en iSavvix)

<%! public class Partido {


String juegaEnCasa;
String juegaFuera;
boolean[] pronostico = new boolean[3];
public String getJuegaEnCasa() {
return this.juegaEnCasa;
}
public void setJuegaEnCasa( String
_newVal) {
this.juegaEnCasa = _newVal ;
}
public String getJuegaFuera() {
return this.juegaFuera;
}
public void setJuegaFuera( String
_newVal) {
this.juegaFuera = _newVal ;
}
public boolean[] getPronostico() {
return this.pronostico;
}
public void setPronostico(boolean[]
_newVal) {
for ( int i = 0; i < 3; i ++ ) {
pronostico[i] = _newVal[i];
}
}
}%>
<%! Partido estePartido = new Partido();
%>
<html>
<head><title>Resultado de un partido - con
scriptlets</title></head>
<%@ include file='cabecera.jsp' %>
<h1>Ejemplo 2: Resultados de la
quiniela</h1>
<table border borderwidth='1'>
<tr><th colspan="2">Partido</th><th
colspan="1">Pronostico</th></tr>
<% estePartido.setJuegaEnCasa( "Madrid" );

estePartido.setJuegaFuera("Barcelona"
);
boolean[] pronostico = new
boolean[3];
for ( int i = 0; i < 3; i ++ ) {
pronostico[i] = true;
}
estePartido.setPronostico(
pronostico ); %>
<td><%= estePartido.getJuegaEnCasa() %>
</td><td> <%= estePartido.getJuegaFuera()
%>
<%! boolean[] estePronostico =
estePartido.getPronostico(); %>
<td><% if (estePronostico[0] ){ %>1 <% }
%><% if (estePronostico[1] ){ %>X <% } %>
<% if (estePronostico[2] ){ %>2 <% } %>
</table>
<%@ include file='pie.jsp' %>

El JSP es un poco extenso, sobre todo por el


código Java insertado. Este código crea una clase
llama Partido, que consta de los dos equipos que
juegan, en casa y fuera, y del pronóstico. El
pronóstico se define como un array de 3
booleanos, uno para cada resultado posible; 1, X
o 2 (gana el equipo de casa, empate o gana el de
fuera). Los pronósticos se pueden combinar (son
las llamadas apuestas múltiples), de forma que un
posible resultado a un partido puede ser X, 12 o
incluso 1X2. La clase se compone de tres pares de
métodos, para establecer el valor (set) de una
variable, y para devolver (get) el valor de la
misma.

A continuación, se crea una instancia de la


clase llamando a new; el objeto estePartido
contendrá el valor de la variable, y lo compartirán
todas las llamadas al JSP. No es que sirva de
mucho la compartición, pero lo hemos dejado así.

Unas líneas más abajo se usa la etiqueta


jsp:include, nuestra primera etiqueta JSP. Es una
orden específica de JSP, que en el servidor, antes
de crearse la respuesta que se envíe al cliente, se
ejecutará, incluyendo, en este caso, un fichero
JSP (o uno HTML). Si se trata de un fichero JSP,
este fichero, a su vez, se interpretará y se incluirá
el resultado en la página. Esto se puede hacer
también de la forma siguiente:

<%@ import file='cabecera.jsp' >

con la diferencia de que, en este caso,


primero se incluye el contenido del fichero y luego
se interpreta. import es una directiva de tiempo de
compilación, mientras que jsp:include actúa en
tiempo de ejecución. En este caso, se incluye una
pequeña cabecera común a todos los ejercicios,
de la misma forma que, al final del fichero, se
incluye un pie, que cierra el fichero HTML y los
cambios de fuente.

En el siguiente scriptlet se establecen los


valores de las variables llamando a los métodos
set, para después recuperarlos dentro de una
tabla, usando los métodos get; el resultado del
array booleano que devuelve getPronostico se tiene
que formatear para convertirse en 1X2

En realidad, para lo que hemos hecho,


podíamos habernos ahorrado tanta clase y tanto
JSP y tanta gaita, pero nos sirve para introducir
un concepto que resulta terriblemente útil en el
mundo del JSP: las habichuelas o beans. Los
beans están definidos por un estándar de Sun, y
tienen cierta complejidad, pero desde el punto de
vista de los JSPs son simplemente clases en las
cuales las variables pueden ser accedidas
mediante métodos set (para cambiar su valor) y
get para recuperar su valor; los métodos set se
llaman con un sólo argumento del mismo tipo que
la variable de instancia, y los métodos get
devuelven un objeto del tipo de la variable de
instancia, sin tomar ningún argumento. No todos
los métodos set tienen que corresponder a una
variable de instancia, ni tampoco los get; pero
todos los métodos que devuelvan un valor tienen
que tener esa estructura, igual que todos los que
alteren un valor. La clase Partido anterior es un
Bean, igual que lo es la siguiente, ligeramente
ampliada (quiniela/Partido.java):

package quiniela;

public class Partido {

String juegaEnCasa;
String juegaFuera;
boolean[] pronostico = new boolean[3];
String unoequisdos="1X2";

public String getJuegaEnCasa() {


return this.juegaEnCasa;
}
public void setJuegaEnCasa( String
_newVal) {
this.juegaEnCasa = _newVal ;
}
public String getJuegaFuera() {
return this.juegaEnCasa;
}
public void setJuegaFuera( String
_newVal) {
this.juegaFuera = _newVal ;
}
public boolean[] getPronostico() {
return this.pronostico;
}
public void setPronostico(boolean[]
_newVal) {
this.pronostico = pronostico;
}
public void
setPronosticoAsString(String _newVal) {
for ( int i=0; i < 3; i++ ) {
if (
_newVal.indexOf(this.unoequisdos.charAt(i)
) >= 0 ) {
this.pronostico[i] =
true;
} else {
this.pronostico[i] =
false;
}
}
}
public String getAsString() {
String str=this.juegaEnCasa + "-"
+ this.juegaFuera + ": ";
for ( int i = 0; i < 3; i ++ ) {
if ( this.pronostico[i] ) {
str +=
this.unoequisdos.charAt(i);
}
}
return str;
}

public String getFormatted() {


String str= "<tr><td>" +
this.juegaEnCasa + "</td><td>" +
this.juegaFuera + "</td>";
for ( int i = 0; i < 3; i ++ ) {
if (this. pronostico[i] ) {
str += "<td>" +
unoequisdos.charAt(i)+ "</td>";
} else {
str += "<td
bgcolor=black> </td>";
}
}
str += "</tr>";
return str;
}
}

Los beans se pueden usar fácilmente desde


los JSPs, usando etiquetas. El JSP anterior se
puede poner de la forma siguiente, usando beans
(resultado.jsp; el resultado en acción es
prácticamente igual al caso anterior):

<%@ page import = "quiniela.Partido" %>

<jsp:useBean id="estePartido"
class="quiniela.Partido" />
<jsp:setProperty name="estePartido"
property="juegaEnCasa" value="Madrid" />
<jsp:setProperty name="estePartido"
property="juegaFuera" value="Barça" />
<jsp:setProperty name="estePartido"
property="pronosticoAsString" value="1X2"
/>
<html>
<head><title>Resultado de un
partido</title></head>
<%@ include file ="cabecera.jsp" %>
<h1>Resultados de la quiniela</h1>
<table border borderwidth='1'>
<tr><th colspan="2">Partido</th><th
colspan="3">Pronostico</th></tr>
<jsp:getProperty name="estePartido"
property="formatted" />
</table>
<%@ include file ="pie.jsp" %>

Antes de que esto funcione, hay que compilar


la habichuela y ponerla en su sitio
correspondiente. En este caso, tendremos que
colocarla en el subdirectorio WEB-
INF/classes/quiniela; las dos primeras partes
corresponden al camino en el que hay que colocar
todos los .class, y quiniela es el nombre del
package en el que hemos metido nuestra clase
Partido. Todas las clases compiladas de este
paquete tendrán que ir a ese directorio. Los JARs
irán también dentro de su directorio
correspondiente, así como otros ficheros que no
se destinan directamente a servirse al público.

El JSP usa la orden en tiempo de compilación


explicada anteriormente para importar la
habichuela dentro del contexto de la página.
Posteriormente, declara un bean llamado
estePartido mediante la etiqueta jsp:useBean. Esta
etiqueta crea un Bean de una clase determinada;
es el equivalente a llamar a new en Java. Las
propiedades de ese bean (las variables accesibles
mediante get y set) se usarán a través de los
métodos jsp:getProperty y jsp:getProperty; es decir,
<jsp:setProperty name="estePartido"
property="juegaEnCasa" value="Madrid" /> es equivalente
a estePartido.setJuegaEnCasa( "Madrid" ). El atributo
property incluye a la propiedad a la que se va a
acceder; a esa propiedad se pone la primera letra
en mayúscula y se le precede con get o set para
hallar el método de la clase al que hay que llamar.
Las líneas siguientes establecen los valores de las
tres propiedades del bean. Posteriormente, se
imprimen los valores devueltos por esas
propiedades. Únicamente hay que fijarse un poco
en la propiedad formatted; en realidad, consiste en
una llamada a un método sin correspondencia con
ninguna variable de instancia; al JSP le da
exactament igual, y llama al método
correspondiente.

Como los errores no son muy informativos,


muchas veces no queda otro remedio que leer
bien leido el código de error, y mirar las fuentes,
a ver qué es lo que le ha molestado. En estas
cosas, como en otras muchas, la experiencia es
un grado.

Ejercicios 3
1. Crear un bean para una pregunta a una
encuesta y su respuesta correspondiente, y
un JSP que lo presente en pantalla.
2. Modificar el JSP anterior para que
presente los 14
resultados de la
quiniela.
Contenido de esta sección
 Acceso a
5 Páginas objetos
implícitos
dinámicas.  Contenido
dinámico
Como para  Excepciones
hacer páginas
estáticas, ya
tenemos el HTML propiamente dicho, vamos a
meter un poco de dinamismo en las páginas,
permitiendo que se modifique la página según
cómo se la llame. Más adelante veremos cómo
hacer que el usuario introduzca esos datos
directamente. Para empezar, haremos que la
página varíe dependiendo de la forma cómo se la
invoque, en la pagina siguiente (resultadoDyn.jsp)

<%@ page import = "quiniela.Partido" %>


<jsp:useBean id="estePartido"
class="quiniela.Partido" />
<jsp:setProperty name="estePartido"
property="*" />
<html>
<head><title>Resultado de un partido
dinámico</title></head>
<-- El
resto
igual
-->

En
este
caso,

usamos, igual que en los ejemplos anteriores,


jsp:setProperty, pero ahora le asignamos valores a
todas las propiedades a la vez tomándolas de los
argumentos con los que se llama el JSP; si lo
llamamos de la forma siguiente
http://localhost:8080/jmerelo/resultadoDyn.jsp?juegaEnCas
a=Osasuna&juegaFuera=Villareal&pronosticoAsString=X;
se
llamarán a las tres propiedades correspondientes,
y se les asignará el valor indicado. La sintaxis que
se sigue en esas llamadas es
nombredel.jsp?variable=valor&variable=valor, y así
sucesivamente. Es la sintaxis normal para pasar
valores a los programas que se ejecutan en el
servidor, tal como los JSPs. El resultado se puede
ver en la imagen

Al usar los parámetros que se pasan al JSP,


estamos utilizando en realidad un objeto implícito
del JSP, el objeto request, una instancia de la clase
javax.servlet.http.HttpServletRequest, exactamente
igual que se usa en los servlets (y es que, en
realidad, se tratan de la misma cosa). Podemos
acceder a él tal como se hace en el siguiente
ejemplo (resultadoDyn2.jsp), que sólo varía unas
líneas con respecto al anterior:

<tr><td colspan='5'><em>Comentario</em><%
if
(request.getParameter("pronosticoAsString"
) == "X" ) { %>
Empate
<% } else if
(request.getParameter("pronosticoAsString"
) == "1" ) { %>
Gana el de casa
<% } else { %>
Gana visitante
<% } %> </td></tr>

Aquí estamos usando el objeto implícito


request, llamando a su método getParameter para
obtener el valor del parámetro de llamada
pronosticoAsString. Este objeto tiene los mismos
métodos que el equivalente de servlets, así que
no nos extendemos más en él. Los más útiles son
el anterior, getParameterNames y getParameterValues;
otros, tales como getCookies, se usarán para
obtener las cookies del cliente. En este caso, se
incluirán en la salida diferentes cadenas
dependiendo del valor del pronóstico; si es un
resultado múltiple, no se incluirá nada.
Hay otros objetos implícitos; probablemente
los más usados sean session, que maneja las
variables de sesión, y application, con métodos
relativos al contexto dónde se está ejecutando el
servlet al que corresponde el JSP.

¿Qué puede ocurrir si alguno de los


parámetros pasados tiene un valor inválido? Por
ejemplo, se podían validar que los equipos
correspondieran a la misma división, o que los
pronósticos estén siempre compuestos de 1, equis
o doses; hasta el momento, no se hace ningún
tipo de comprobación. Para ello, tendremos que
modificar ligeramente el bean, haciendo que el
método setPronosticoAsString tire una excepción si
se encuentra con un carácter inválido en la
cadena que se le pasa. Después de cambiarle el
nombre a la clase ( quiniela/PartidoValidado.java):

public void setPronosticoAsString(String


_newVal) throws RuntimeException{
if (_newVal.length() > 3)
throw new RuntimeException (
"Pronóstico más largo de la cuenta" );
if (_newVal.length() == 0)
throw new RuntimeException (
"No hay pronóstico" );
for ( int j = 0; j <
_newVal.length(); j ++ ) {
if ( _newVal.charAt(j) !=
'1' && _newVal.charAt(j) != 'X'
&& _newVal.charAt(j)
!= '2' ) {
throw new
RuntimeException ( "Carácter raro en
cadena:"+ _newVal.charAt(j) + " en la
posición " + j );
}
}
for ( int i=0; i < 3; i++ ) {
if (
_newVal.indexOf(this.unoequisdos.charAt(i)
) >= 0 ) {
this.pronostico[i] =
true;
} else {
this.pronostico[i] =
false;
}
}
}

Con respecto a la versión anterior, se han


añadido una serie de comprobaciones de longitud
excesiva, demasiado pequeña, o si hay algún
carácter que no sea 1X2. Capturar la excepción en
un programa en Java es fácil (con las sentencias
try y catch), pero, en un JSP nos encontraremos
algo así:

java.lang.reflect.InvocationTargetExceptio
n: java.lang.RuntimeException: Pronóstico
más largo de la cuenta
at

quiniela.PartidoValidado.setPronosticoAsString(P
artidoValidado.java:31)

Para ello se usan las páginas de error, que se


llaman en caso de que se haya producido una
excepción; es más o menos lógico que no se
traten las excepciones dentro de la misma página,
porque, en algunos casos, pueden producirse
antes incluso de que el código haya sido
generado. Para usar la página de error, incluimos
al principio del fichero ( resultadosDynVal.jsp):

<%@ page
errorPage="paginaError.jsp?debug=log" %>
<% request.setAttribute("paginaOrigen",
request.getRequestURI()); %>
Con esto se declara una página de error, y se
asigna un atributo a la petición, que almacenará
el URI de la peticición, es decir, el camino con el
que se la ha llamado. El código de la página de
error es el siguiente ( paginaError.jsp):

<%@ page isErrorPage="true" %>


<html>
<head><title>Se ha producido un
error</title></head>
<%@ include file ="cabecera.jsp" %>
<h1>Se ha producido un error</h1>

<p>Endeluego, que a ver si tenemos


cuidaico, que se ha producido el siguiente
error:<br>
<%= exception.getMessage() %> en la página
<%=
request.getAttribute("paginaOrigen") %>
<%@ include file ="pie.jsp" %>

Lo más importante es la primera línea: la


página se declara a sí misma como una página
que responde a los errores, lo cual permite que se
cree el objeto implícito exception. Ese objeto se usa
más adelante para imprimir el mensaje que se ha
producido (aunque no siempre funciona). También
se recupera un atributo del objeto implícito
request, que había sido puesto por la página que
ha producido el error, para que se sepa de dónde
procede el error. Cuando se produzca alguna
entrada errónea, por ejemplo,
pronosticoAsString=123, se producirá una excepción
en el objeto PartidoValidado, que se propagará al
JSP que la contiene, que a su vez llamará a esta
página de error

Ejercicios 4
1. Cambiar la encuesta para que tome los
resultados de los parámetros que se le
pasen al JSP .
2. Cambiar la EncuestaBean para que
detecte errores (tales como una respuesta
incorrecta), y levante una excepción; crear
una página de error que capture esa
excepción y la
muestre.
Contenido de esta sección
6  Formularios
 Combinación
Procesamient de elementos
JSP
o de  Ámbitos
 Taglibs
formularios
Ya está bien de tanto objeto implícito y tanta
gaita, vamos a ir directamente al turrón de
procesar formularios como Dios manda. Vamos a
tratar de hacer una página JSP que cree y a la vez
procese el formulario; de esta forma es más fácil
de mantener. El formulario nos permitirá rellenar
la quiniela sin hacer nada en concreto con ella,
sólo presentarla. En la práctica, habría
probablemente que almacenar los resultados en
una base de datos, o por lo menos un fichero,
pero por lo pronto, lo dejaremos así. El formulario
se implementa en el código siguiente:(quiniela.jsp,
que usa la clase Quiniela:)

<%@ page import = "quiniela.*" %>


<jsp:useBean id='estaQuiniela'
class="quiniela.Quiniela"
scope='request'/>
<jsp:setProperty name='estaQuiniela'
property='inputFile' value=
"/home/jmerelo/public_html/JSP/quiniela.da
t" />
<html>
<head>
<title>Rellena tu quiniela</title>
</head>
<%@ include file ="cabecera.jsp" %>
<h1>Rellena tu quiniela</h1>
<form action='quiniela.jsp' method='get' >
<% for ( int i = 0; i <
estaQuiniela.getNumPartidos(); i ++ ) {
String proStr = "pronostico"+i;
try { %>
<jsp:setProperty name='estaQuiniela'
property='numPartido' value="<%= i %>" />
<% if (
request.getParameter("pronostico0") !=
null ) { %>
<jsp:setProperty name='estaQuiniela'
property='pronosticoAsString' value="<%=
request.getParameter( proStr) %>" />
<% } else { %>
<jsp:setProperty name='estaQuiniela'
property='pronosticoAsString' value="1X2"
/>
<% }
} catch (Exception _e ) {
System.err.println( "Esto no
debiera pasar: " + _e.getMessage() );
}
}%>
<table border>

<tr><th> </th><th>Partido</th><th>Pronósti
co</th><th>Pronóstico Anterior</th>
</tr>
<% for ( int i = 0; i <
estaQuiniela.getNumPartidos(); i ++ ) {
String proStr = "pronostico"+i;
%>
<tr><td><%= i %></td>
<jsp:setProperty name='estaQuiniela'
property='numPartido' value="<%= i %>" />
<td><jsp:getProperty name='estaQuiniela'
property='juegaEnCasa' />-
<jsp:getProperty name='estaQuiniela'
property='juegaFuera' /></td>
<td><input
type='text' name='pronostico<%= i %>'
value='<jsp:getProperty
name='estaQuiniela' property='pronostico'
/>' ></td>

<td><jsp:getProperty
name='estaQuiniela' property='pronostico'
/> </td>
</tr>
<% } %>
<tr><td colspan="4" align="center"><input
type='submit' ></td>
</tr>
</table>

</form>
<%@ include file ="pie.jsp"
%> Para quien no haya trabajado
Para empezar, hemos con formularios (ver por
creado un nuevo bean que ejemplo este tutorial de
contiene un vector de formularios o bien este
partidos, llamado Quiniela; tutorial de HTML, que
incluye también formularios)
este bean será el que
usemos en la página; en general, es una buena
idea reflejar la estructura de una página en un
bean, o viceversa. En el caso anterior usábamos
los beans Partido y PartidoValidado, y en este caso
usamos esta. La única peculiaridad de esta clase
es que, debido a su estructura como Bean, no se
puede llamar a ningún método con dos
argumentos, por lo que tenemos que establecer
un cursor de partido que indique sobre qué
partido van a actuar los métodos que ponen o
extraen valores de la clase
El objeto que va a contener la quiniela se
declara en las primeras líneas, mediante el tag
<jsp:useBean>. A continuación se le pasa el fichero
quiniela.dat, que contiene los datos de una quiniela
(de primera división universal especial, como se
puede comprobar). A continuación, después de
abrir el formulario, se detecta si se ha usado uno
de los datos del mismo (pronostico0), en cuyo caso
se empieza a procesarlo: se crea una cadena con
el nombre del parámetro (pronostico + el índice),
se usa esa cadena para colocar el cursor
(%lt;jsp:setProperty name='estaQuiniela'
property='numPartido' value="<%= i %>" />) y se asigna
el pronóstico al partido correspondiente de la
quiniela. Como se ve, este formulario sirve para
las dos cosas: para recibir las entradas, y para
procesarlas.

En las siguientes líneas se presentan los


resultados que se han introducido lado a lado con
una serie de cuadros de texto que permiten
cambiar el pronóstico.

Este código se puede mejorar un tanto,


evitando errores en origen poniendo checkboxes
(es decir, cuadraditos sobre los cuales se puede
pinchar) en vez de introducirlo mediante el
teclado. Eso no quiere decir que se tenga que
eliminar el código de corrección de errores,
porque siempre se puede modificar a mano la
petición al servidor. Simplemente, se le evitan
problemas al usuario. Eso se hace en la siguiente
versión quinielaBoton.jsp:

<!-- El principio es similar >


<% for ( int i = 0; i <
estaQuiniela.getNumPartidos(); i ++ ) {
String proStr = "pronostico"+i;
String strPronostico ="";
String[] params =
request.getParameterValues( proStr );%>
<jsp:setProperty name='estaQuiniela'
property='numPartido' value="<%= i %>" />
<% if (
request.getParameter("submit") != null ) {
for ( int j = 0; j <
params.length; j ++ ) { strPronostico +=
params[ j ]; }
%>
<jsp:setProperty name='estaQuiniela'
property='pronosticoAsString' value="<%=
strPronostico % >" />
<% } else { %>
<jsp:setProperty name='estaQuiniela'
property='pronosticoAsString' value="1X2"
/>
<% }
}%>
<table border>
<tr><th rowspan='2'> </th><th
rowspan='2'>Partido</th><th
colspan='3'>Pronóstico</th><th
rowspan='2'>Pronóstico Anterior</th>
</tr>

<tr><td>1</td><td>X</td><td>2</td>
</tr>
<% for ( int i = 0; i <
estaQuiniela.getNumPartidos(); i ++ ) {
String proStr = "pronostico"+i;
%>
<tr><td><%= i %></td>
<jsp:setProperty name='estaQuiniela'
property='numPartido' value="<%= i %>" />
<td><jsp:getProperty name='estaQuiniela'
property='juegaEnCasa' />-
<jsp:getProperty name='estaQuiniela'
property='juegaFuera' /></td>
<% boolean[] pronosticos
= estaQuiniela.getPronostico();
for ( int j = 0; j < 3; j
++ ) { %>
<td><input type='checkbox'
name='pronostico<%= i %>' value='<%=
quiniela.PartidoValidado.get1X2( j ) %>'
<%= pronosticos[j]==true?"checked":"" %>'
></td>
<% } %>

<td><jsp:getProperty
name='estaQuiniela'
property='pronosticoAsString' /> </td>
</tr>
<% } %>
<tr><td colspan="4" align="center"><input
type='submit' name='submit'
value='Enviar'></td>
</tr>
</table>

</form>

El truqui del asunto está al principio: en


vez de usar getParameter para coger un solo
parámetro, se usa getParameterValues, que devuelve
un array con todos los valores que tiene un
parámetro; en este caso, cada grupo de 3
botones usa el mismo nombre de elemento del
formulario, por eso cada parámetro tendrá tantos
elementos como botoncitos se hayan rellenado.
En todo caso, se pegan los parámetros en una
sola cadena, que se usa para asignarle un valor al
pronóstico.

En cuanto al formulario, en este caso


tenemos que usar el pronóstico como un array de
valores booleanos (en vez de una cadena como
hacíamos anteriormente), porque nos conviene
más a la hora de poner el valor por defecto a los
botones. Usamos también un método de clase de
Java, para pasar de un índice de 0 a 2 al símbolo
correspondiente (1, X o 2).

Pero claro, lo interesante no es sólo presentar


los datos del formulario, sino agregarlos en unas
estadísticas para toda la oficina (y de camino,
fastidiar al asaúra mostrándole que su pronóstico
no lo comparte nadie) y presentarlos en un
gráfico chuli. Eso lo haremos en el siguiente
programa (stats.jsp):

<%@ page import="quiniela.*" %>

<jsp:useBean id='stats'
class='quiniela.Stats' scope='application'
/>
<jsp:useBean id='estePartido'
class="quiniela.PartidoValidado"
scope='request' />
<jsp:setProperty name='estePartido'
property='juegaEnCasa' value= "Valencia"
/>
<jsp:setProperty name='estePartido'
property='juegaFuera' value= "Inter" />

<-- El resto similar a los anteriores -->


<%@ include file ="pie.jsp" %>

Este fichero es similar a los anteriores que se


han tratado, pero en este caso se usa un bean
que tiene ámbito de aplicación, indicándolo con
scope='application' . Eso significa que va a poder
ser "visto" por todos los demás servlets y JSPs del
servidor; sería algo así como una variable del
servidor. Esto lo vamos a usar para poder
compartir información entre diferentes
invocaciones y diferentes JSPs.

Hay cuatro ámbitos diferentes en las


variables usadas en JSPs y servlets:
 el ámbito de página: objetos que sólo están
accesibles durante la ejecución del código de
una página
 petición: objetos compartidos entre las
diferentes páginas que manejan una
petición, por ejemplo, una página y la que
maneje errores de la primera, o una página
y otra a la que se pasa control con la orden
jsp:forward
 sesión; objetos compartidos entre las
diferentes páginas que se llamen a través de
una sesión, y, por último
 aplicación, compartidos por todos los objetos
dentro del servidor

Este último ámbito es el que usamos


precisamente en esta página. Para
entendernos, serían como una especie de
objetos persistentes, que estarán ahí hasta
que rearranquemos el servidor. Y
precisamente eso es lo que vamos a hacer,
usarlos para ver esas estadísticas en plan
chuli (viewstats.jsp).

<%@ taglib uri="bartag.jar"


prefix="bar" %>
<%@ page import="quiniela.*" %>
<jsp:useBean id='stats'
class='quiniela.Stats'
scope='application' />
<html>
<head>
<title>Ver Estadísticas de la
quiniela</title>
</head>
<%@ include file ="cabecera.jsp" %>
<h1>Ver Estadísticas de la
quiniela</h1>
<table border>
<tr><th>Partido</th><th
colspan='2'>Estadísticas</th>
</tr>
<tr>
<td>Alcorcón - Vitigudino</td>
<td><bar:Hbar values="<%=
stats.getAsString() %>"
fgcolor="#FF0000" width="220"
labels="1,X,2" bgcolor="#0000FF" />
</td>
<td><%= stats.getAsString()
%></td>
</tr>
</table>
<%@ include file ="pie.jsp" %>

L
a
s

n
o
v
e
d
a
d
e
s

de este nuevo fichero empiezan pronto: en


la primera línea. Los gráficos no es algo que
se pueda hacer con JSPs así, a pelo, así que
usamos una librería de etiquetas, una tag
library. En este caso se trata de la librería
barchart, una taglib para hacer gráficos de
barras horizontales y verticales. Instalarla es
fácil: hacen falta dos ficheros: el archivo de
clases de java, .jar, y una descripción de las
etiquetas y su correspondencia con métodos
y clases, .tld. Cada uno de estos ficheros
suele ir a un sitio diferente: el primero a WEB-
INF/lib y el segundo a WEB-INF/tlds. También
pueden ir al mismo directorio donde esté el
fichero correspondiente, pero será más
complicado de usar desde otros JSPs. La
taglib esta también está disponible en
iSavvix, entre otras muchas

Las taglibs son simplemente un cambio


de interface con respecto al código Java
normal; te ahorran insertar código dentro de
las páginas, y son, en general, más fáciles
de mantener, porque, en el más puro estilo
OO, encapsulan su lógica y el que las usa no
tiene que preocuparse por cómo hacen lo
que hacen, sólo por acceder a ellas. Hay
muchas gratuitas, y hay colecciones tales
como esta de JSPin. Sin embargo, la que
usamos aquí no lo es, y sólo permite cinco
datos simultáneos, así que tendremos que
hacer un gráfico chiquitito.

En este caso no nos hemos complicado


la vida y hemos puesto directamente el
fichero en el mismo directorio que el fichero
JSP correspondiente; eso lo indicamos con
uri="bartag.jar" ; además, tenemos que
definir el prefijo (en realidad, el espacio de
nombres) que vamos a usar para referirnos
a esa taglib: en este caso prefix="bar" indica
que el prefijo va a ser bar (barra).

Con esta taglib se pueden hacer barras


horizontales y verticales; nosotro susamos
las barras horizontales bar:Hbar, a las que hay
que pasarle los valores que se quieren
representar separados por comas, y otra
serie de atributos que establecen los colores,
la anchura y las etiquetas de cada uno de los
valores que se le han pasado. El resultado es
el que se muestra en la figura.

Ejercicios 5
1. Hacer un formulario con una
encuesta que guarde estadísticas
sobre las respuestas contestadas
2. Usar una librería de etiquetas que
incluya bucles, y convertir algún
JSP anterior que use bucles java a
uno que use los bucles de la taglib.
3. Hacer un JSP que contenga un
carrito de la compra usando beans
con ámbito de sesión.

7 Bibliografía y enlaces
relacionados con JSP
Enlaces en Internet
Para empezar, hay que mencionar el
debate generado por la publicación de este
debate en Barrapunto, donde puedes
participar si quieres:
http://barrapunto.com/article.pl?sid=02/03/
18/0837221. En la discusión sugieren otras
alternativas, enlaces interesantes, y discuten
las ventajas e inconvenientes de los JSPs
frente a otras alternativas.

El más popular en Amazon parece ser Beginning JSP


Web Development by Jayson Falkner (Editor), John
Timney, Casey Kochmer, Romin Irani, Perrumal
Krishnaraj, Meeraj Moidoo Kunnumpurath, Sathya
Narayana Panduranga, Ben Galbraith. Uno de los
clásicos "libros rojos" de Wrox press, explica todos los
aspectos de la programación con JSP: librerías de
etiquetas, programación con base de datos, Tomcat...
Como siempre, los libros de O'Reilly son garantía de
calidad, y JavaServer Pages (segunda edición) by Hans
Bergsten no podía ser menos. Un poco más condensado
que el anterior, explica inicialmente HTTP y los
servlets, para meterse luego en profundidad en faena
hablando de sesiones, acceso a base de datos,
programación con XML y otras cosas que se hacen
habitualmente con JSPs. También se puede acceder
desde Safari, en caso de que estés suscrito a ese servicio
.
y a la referencia de bolsillo

Juan Julian Merelo Guervos


Last modified: Fri Oct 22 11:01:20 CEST 2004

También podría gustarte