JSP
JSP
JavaServer Pages (JSP) es una tecnologa Java que permite generar contenido dinmico para web, en forma de documentos HTML, XML o de otro tipo. Esta tecnologa es un desarrollo de la compaa Sun Microsystems. La Especificacin JSP 1.2 fue la primera que se liber y en la actualidad est disponible la Especificacin JSP 2.1. Las JSP's permiten la utilizacin de cdigo Java mediante scripts. Adems, es posible utilizar algunas acciones JSP predefinidas mediante etiquetas. Estas etiquetas pueden ser enriquecidas mediante la utilizacin de Bibliotecas de Etiquetas (TagLibs o Tag Libraries) externas e incluso personalizadas.
Arquitectura
JSP puede considerarse como una manera alternativa, y simplificada, de construir servlets. Es por ello que una pgina JSP puede hacer todo lo que un servlet puede hacer, y viceversa. Cada versin de la especificacin de JSP est fuertemente vinculada a una versin en particular de la especificacin de servlets. El funcionamiento general de la tecnologa JSP es que el Servidor de Aplicaciones interpreta el cdigo contenido en la pgina JSP para construir el cdigo Java del servlet a generar. Este servlet ser el que genere el documento (tpicamente HTML) que se presentar en la pantalla del Navegador del usuario.
JSP -> Servidor Aplicaciones (Servlets) -> Cliente (Navegador)
Es posible enriquecer el lenguaje de etiquetas utilizado por JSP. Para ello debemos extender la capa de alto nivel JSP mediante la implementacin de Bibliotecas de Etiquetas (Tags Libraries). Un ejemplo de estas bibliotecas son las propocionadas por Sun bajo la denominacin de JSTL o las distribuidas por Apache junto con el Framework de Struts.
TagLibs -> JSP -> Servidor Aplicaciones (Servlets) -> Cliente (Navegador)
El rendimiento de una pgina JSP es el mismo que tendra el servlet equivalente, ya que el cdigo es compilado como cualquier otra clase Java. A su vez, la mquina virtual compilar dinmicamente a cdigo de mquina las partes de la aplicacin que lo requieran. Esto hace que JSP tenga un buen desempeo y sea ms eficiente que otras tecnologas web que ejecutan el cdigo de una manera puramente interpretada. La principal ventaja de JSP frente a otros lenguajes es que el lenguaje Java es un lenguaje de propsito general que excede el mundo web y que es apto para crear clases que manejen lgica de negocio y acceso a datos de una manera prolija. Esto permite separar en niveles las aplicaciones web, dejando la parte encargada de generar el documento HTML en el archivo JSP.
Otra ventaja es que JSP hereda la portabilidad de Java, y es posible ejecutar las aplicaciones en mltiples plataformas sin cambios. Es comn incluso que los desarrolladores trabajen en una plataforma y que la aplicacin termine siendo ejecutada en otra. Los servlets y Java Server Pages (JSPs) son dos mtodos de creacin de pginas web dinmicas en servidor usando el lenguaje Java. En ese sentido son similares a otros mtodos o lenguajes tales como el PHP, ASP o los CGIs, programas que generan pginas web en el servidor. Sin embargo, se diferencian de ellos en otras cosas. Para empezar, los JSPs y servlets se ejecutan en una mquina virtual Java, lo cual permite que, en principio, se puedan usar en cualquier tipo de ordenador, siempre que exista una mquina 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 peticin, sino que persiste de una peticin a la siguiente, de forma que no se pierde tiempo en invocarlo (cargar programa + intrprete). Su persistencia le permite tambin hacer una serie de cosas de forma ms eficiente: conexin a bases de datos y manejo de sesiones, por ejemplo. Las JSPs son en realidad una forma alternativa de crear servlets ya que el cdigo JSP se traduce a cdigo de servlet Java la primera vez que se le invoca y en adelante es el cdigo del nuevo servlet el que se ejecuta produciendo como salida el cdigo HTML que compone la pgina web de respuesta.
import ... class _myservlet implements javax.servlet.Servlet, javax.servlet.jsp.HttpJspPage { //insertado como //resultado de <%! int serverInstanceVariable = 1;%> int serverInstanceVariable = 1; ... public void _jspService( javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response ) throws javax.servlet.ServletException, java.io.IOException { javax.servlet.ServletConfig config = ...;//obtener la configuracin del servlet Object page = this; PageContext pageContext = ...;//obtener el contexto de la pagina para esta peticin javax.servlet.jsp.JspWriter out = pageContext.getOut(); HttpSession session = request.getSession( true ); ...
Para ejecutar las pginas JSP, se necesita un servidor Web con un contenedor Web que cumpla con las especificaciones de JSP y de Servlet. Tomcat 5 es una completa implementacin de referencia para las especificaciones Java Servlet 2.2 y JSP 1.1.
[editar] Sintaxis
[editar] Variables Implcitas
Las pginas JSP incluyen ciertas variables privilegiadas sin necesidad de declararlas ni configurarlas:
Variable Clase
pageContext javax.servlet.jsp.PageContext request response session config javax.servlet.http.HttpServletRequest javax.servlet.http.HttpServletResponse javax.servlet.http.HttpSession javax.servlet.ServletConfig
page exception
java.lang.Object java.lang.Exception
[editar] Directivas
Son etiquetas a partir de las cuales se genera informacin que puede ser utilizada por el motor de JSP. No producen una salida visible al usuario sino que configura cmo se ejecutar la pgina JSP. Su sintaxis es:
<%@ directiva atributo="valor" %>
Atributo
Sintaxis
Utilizacin Importa clases y paquetes Java para ser utilizadas dentro del fichero JSP. Especifica si utiliza los datos contenidos en sesin; por defecto "true". Especifica el tipo MIME del objeto "response"; por defecto "text/html; charset=ISO-8859-1". Buffer utilizado por el objeto writer "out"; puede tomar el valor de "none";
import
session
contentType
buffer
por defecto "8KB". Especifca la ruta de la pgina de error que ser invocada en caso de <%@ page errorPage="/path_to_error_page" %> producirse una excepcin durante la ejecucin de este fichero JSP. Determina si este fichero JSP es una pgina que maneja excepciones. nicamente a este tipo de pginas pueden acceder a la variable impcita "exception", que contiene la excepcin que provoc la llamada a la pgina de error.
errorPage
[editar] Scriptlets
Los scriptlets son partes de cdigo Java incrustadas entre los elementos estticos de la pgina.
<% ... cdigo Java ... %>
El siguiente ejemplo pondra como ttulo de la pgina el atributo "ttulo" contenido en el objeto request:
<% String titulo = ""; if (request.getAttribute("titulo") != null) { titulo = (String) request.getAttribute ("titulo"); }
[editar] Etiquetas
Etiquetas JSP para simplificar el cdigo y dar mayor funcionalidad. Desarrollar sitios web utilizando etiquetas presenta ciertas ventajas como:
facilitar el aprendizaje. facilitar el mantenimiento. fomentar la modularidad y la reutilizacin. simplificar el cdigo y reducir el nmero de lneas necesarias.
Su sintaxis sera:
<%@ taglib uri="/taglib/lycka" prefix="lycka" %> ... <lycka:hola/> ...
A la hora de generar el cdigo Java de la Servlet, esta etiqueta hola ser interpretada por el Servidor de Aplicaciones como perteneciente a la biblioteca de etiquetas (Tag Library) lycka. Esta biblioteca estar identificada en el fichero descriptor de nuestra aplicacin (web.xml) con el nombre de recurso (URI) /taglib/lycka.
<taglib-uri>/taglib/lycka</taglib-uri> <taglib-location>/WEB-INF/tags/lycka.tld</taglib-location>
Y por fin, el servidor de aplicaciones sustituir la etiqueta por su cdigo Java asociado, org.lcyka.taglibs.miEtiqueta:
package org.lcyka.taglibs; import ...; public class miEtiqueta extends TagSupport { public int doStart { try { pageContext.getOut().print("Mi gata es preciosa"); } catch (IOException ioe) { } return SKIP_BODY; }
Son las etiquetas pertenecientes a la especificacin JSP. Proporcionan una funcionalidad bsica. Un primer grupo de etiquetas proporciona funcionalidad a nivel de la pgina de una manera muy simple:
<jsp:forward>, redirige la request a otra URL <jsp:include>, incluye el texto de un fichero dentro de la pgina <jsp:plugin>, descarga un plugin de Java (una applet o un Bean).
<jsp:useBean>, permite manipular un Bean (si no existe, se crear el Bean), especificando su mbito (scope), la clase y el tipo. <jsp:getProperty>, obtiene la propiedad especificada de un bean previamente declarado y la escribe en el objeto response. <jsp:setProperty>, establece el valor de una propiedad de un bean previamente declarado.
xml, para la manipulacin de XML y para XML-Transformation. sql, para gestionar conexiones a bases de datos. i18n, para la internacionalizacin y formateo de las cadenas de caracteres como cifras.
Anteriormente hemos visto un ejemplo para crear una etiqueta personalizada almacenada en nuestra propia biblioteca de etiquetas. Para desarrollar etiquetas personalizadas, utilizaremos la API de las bibliotecas de etiquetas (Tag Libraries). La API de las Servlet de Java es:
javax.servlet.*
Finalmente, la API de las bibliotecas de etiquetas (Tag Libraries) extiende de esta ltima,
javax.servlet.jsp.tagext.*
Las interfaces o Tag, que todas las etiquetas deben implementar. o BodyTag, extiende a la anterior y define mtodos adicionales para inspeccionar el cuerpo de una etiqueta. Las clases o BodyContent, un manejador (handler) para leer y escribir en el cuerpo de una etiqueta. o BodyTagSupport, que implementa la interfaz BodyTag.
o o o o o o o
TagAttributeInfo, para obtener la informacin de los atributos de la etiqueta declarados en el TLD. TagData, que contiene los valores de los atributos. TagExtraInfo, para especificar informacin extra de una etiqueta, como las variables que introduce en el cdigo o los atributos que sern validados. TagInfo, basado en la informacin de la TLD. TagLibraryInfo, representa la informacin de una TLD. TagSupport, implementa la interfaz Tag. VariableInfo, contiene informacin como el tipo y mbito de las variables creadas o modificadas por la etiqueta.
Podemos encontrar una descripcin ms detallada en http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/jsp/tagext/packagesummary.html Otro ejemplo de etiqueta podra ser el siguiente cdigo Java:
package org.lycka.taglibs; import ...; public class LowerCaseTag extends BodyTagSupport { public int doAfterBody() throws JspException { try { BodyContent body = getBodyContent(); JspWriter writer = body.getEnclosingWriter(); String bodyString = body.getString(); if ( bodyString != null ) { writer.print( bodyString.toLowerCase()); } } catch(IOException ioe) { throw new JspException("Error: IOException while writing to the user"); } return SKIP_BODY; } }
Al encontrar el inicio de la etiqueta, el runtime primero se invocar el mtodo doStart() una vez instanciada la clase. Puede devolver uno de los siguientes valores:
SKIP_BODY, no procesa el contenido del cuerpo de la etiqueta. EVAL_BODY_INCLUDE , evala el cuerpo de la etiqueta. EVAL_BODY_TAG , evala el cuerpo de la etiqueta y lanza el resultado a otro stream almacenado en una propiedad de la etiqueta.
El mtodo doAfterBody() despus de procesar el cuerpo de la etiqueta. Finalmente se invocar el mtodo doEndTag(). Puede devolver:
SKIP_PAGE, para dejar de procesar la pgina JSP, para por ejemplo redirigir la pgina
Y su salida sera
mi gata es tan preciosa.
Ambos necesitan un programa que los contenga, y sea el que enve efectivamente pginas web al servidor, y reciba las peticiones, las distribuya entre los servlets, y lleve a cabo todas las tareas de gestin propias de un servidor web. Mientras que servidores como el Apache estn especialmente pensados para pginas web estticas CGIs, y programas ejecutados por el servidor, tales como el PHP, hay otros servidores especficos 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 pginas XML, con una licencia libre para desarrolladores. Dice ser bastante rpido. Incluye soporte para Javascript adems de Java. Incluye tambin un lenguaje de templates llamado XTP. Es bastante fcil de instalar, y en dos minutos, se pueden empezar a servir pginas JSP. BEA Weblogic es un servidor de aplicaciones de alto nivel, y tambin 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 versin de evaluacin gratuita Lutris Enhydra, otro servidor gratuito y Open Source, aunque tiene una versin de pago. Tambin enfocado a servir XML, y para plataformas mviles. Las versiones ms actualizadas son de pago, como es natural El ms 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 pginas XML. Puede servir pginas slo o bien como un aadido al servidor Apache. Es Open Source, relativamente rpido, y fcil de instalar. La versin actual es la 4.0.3, aunque siguen saliendo versiones de la 3.
Otros muchos se pueden encontrar en la pgina de Sun sobre la industria del servlet/JSP y en la pgina de contenedores de servlets en servlets.com
Contenido de esta seccin Prerrequisitos para instalar un servidor Instalando un contenedor de servlets Ejecutando los primeros JSPs Hosting de servlets, de pago y gratuito
Antes siquiera de bajarse el programa en cuestin, hay que considerar previamente de la mquina virtual Java que vamos a usar para ejecutarlo. Todos estn 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 ms rpidas, pero que no siempre estn actualizadas hasta la ltima versin. Un contenedor de servlets necesita el JDK completo, no slo 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 versin 1.4), o bien la versin 1.3 de IBM (la ms aconsejable). Si no se consigue una versin de esas, es aconsejable conseguir una que sea compatible con la versin "2" de Java, es decir, JVMs a partir de la versin 1.2. Puede que funcionen con versiones anteriores, pero lo ms probable es que no lo hagan. Igual est ya Java instalado en el sistema; habr que verificar que java y tools.jar estn tambin instalados; basta con intentar ejecutarlo, o bien preguntarle al administrador del sistema, que tambin 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 versin binaria, ya compilada. Si disponemos de una distro de Linux que use el RPM para instalacin de paquetes (como Mandrake, RedHat o SuSE), se puede uno bajar los RPMs e instalarlos directamente. Dependiendo de lo que elijamos, habr que bajarse slo 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 despus 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 continuacin, habr que decirle dnde se encuentra la mquina virtual Java, editando un fichero tomcat.conf que se encuentra dentro del directorio conf (que variar de sitio segn la distribucin; puede ser en /etc/tomcat4/conf o en directorio_del_tomcat/conf). En otros sistemas operativos, o con otro tipo de instalacin, 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 intrprete de comandos bash (el primero) o *csh (el segundo). En WinXX habr que dar una orden similar. Finalmente para ejecutar el servidor, fijndonos 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 distribucin 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 direccin tal como http://localhost:8080 o http://localhost:8180 (si quieres usar direcciones por debajo de 1000 tendrs 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 fcil que es decir, joer, que no hay una puetera pgina, caray!. Tambin 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 mquina virtual Java. Una vez que se ha instalado, y se ha comprobado que funciona correctamente, se puede intentar cambiar la configuracin, sobre todo teniendo en cuenta el nmero de visitas esperadas. La mayora de los cambios de configuracin se hacen sobre el fichero conf/server.xml. Para cambiar el puerto en el que se escucha y el nmero de servidores disponibles mnimo y mximo, hay que cambiar la siguiente orden:
<Connector className="org.apache.catalina.connector.http.HttpConnector" port="10001"minProcessors="2" maxProcessors=" 5" enableLookups="true" redirectPort="8543" acceptCount="10" debug="0" connectionTimeout="60000"/>
La configuracin 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 configuracin se ha simplificado mucho desde la versin anterior, aunque introduce nuevos elementos: las vlvulas 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, slo habr que cambiar el nmero mnimo de procesadores (o hebras que sirven peticiones) y el mximo, para no sobrecargar demasiado el sistema en caso de que se cuente con poca memoria principal. El mnimo aceptable es 2, y el mximo 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. Tambin 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 ms recursos iniciando la JVM de forma que se limite el tamao 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 lnea de comandos, ps -exfua. Tambin se puede aadir un nuevo contexto al servidor; sobre todo si queremos que nuestras aplicaciones no se mezclen con el resto de las aplicaciones en el contexto raz (las contenidas en el directorio ROOT. Para ello, se puede aadir, justo despus de la lnea 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 algn navegador, es decir, http://miservidor/micontexto, y el segundo nombre es el subdirectorio del directorio webapps al que se refiere Una vez realizada la aplicacin, 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 . Tambin 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 libreras de tags e incluso XSLT; lo que no permite, es que uno suba sus propias clases, aunque se pueden usar diversas libreras 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 das; ms all de eso, hay que contratar el servicio Premium, a partir de 3$. Por ltimo, MyCGIserver tambin permite alojamiento gratuito; hay que responder a una pregunta relacionada con los servlets, pero es usualmente fcil 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 tambin con el Caucho Resin. El proceso es bastante similar. Cambiar la configuracin de Tomcat de forma que cada conector use slo 2 hebras mnimo, y 5 mximo. Cambiar al puerto al 10001; rearrancar el servidor. Definir un nuevo contexto para los ficheros propios. 2. Darse de alta en algn servidor gratuito, y subir alguno de los ejemplos de Resin o de Tomcat para probarlo.
Si todo va bien, y los ejemplos se ejecutan correctamente, hola.jsp ya est uno listo para crear su primer programa, o pgina, en JSP (depende de como uno lo mire). Como las pginas JSP son bsicamente pginas 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 montn de recursos), el Visual Age for Java; estos dos estn escritos en Java y pueden ejecutarse en cualquier plataforma. El Dreanweaver Ultradev, sin embargo, existe slo en versin 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 pgina JSP (hola.jsp; en accin en iSavvix):
<!-- (c) JJ --> <%@ page language='java' contentType="text/html" %> <%! int count=0; %> <html> <head><title>Hola y nmeros. 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 pgina, habr que ponerla en algn sitio. La estructura de directorios de Tomcat (y de otros contenedores de servlets) es un poco ms 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 raz ROOT y tantos otros contextos como queramos definir. Dentro de cada contexto, la estructura de directorios es tambin siempre la misma; directamente descendiendo del directorio se pueden poner los JSPs, y hay tambin un directorio WEB-INF donde hay una serie de ficheros de configuracin y propiedades, y adems otros directorios: classes y lib (que no aparece en esta imagen). En esos directorios se pondrn ms 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). Tambin se puede colocar en cualquiera de los subdirectorios del directorio webapps, pero no en el principal El fichero contiene la mayora de los elementos de un JSP. Para empezar, la lnea 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 @ despus del comienzo de la orden JSP (<%). En este caso, le indicamos que la pgina que se va a ejecutar est en lenguaje Java, y que el contenido que va a generar es de tipo text/html; el estndar JSP, a pesar de su nombre, no est limitado a un solo lenguaje, aunque en la prctica se usa casi siempre Java, y en algunos casos JavaScript. En cuanto al contenido, JSP trabaja, por defecto, con HTML, pero se podran generar pginas en otros estndares tales como el WML que se usa en los mviles WAP, o XML. La directiva page puede incluir otros atributos:
<%@ page language='java' contentType="text/html" info='Mi primera pgina 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 administracin; import permite especificar una serie de paquetes en Java para importar, y errorPage indica la pgina a la que habra que saltar en caso de que se genere una excepcin. Ahora mismo, ninguno de estos atributos son necesarios, y, de hecho, la pgina funciona perfectamente bien sin ellos; en ese caso, tomara los valores por defecto, es decir, lenguaje HTML para la pgina y Java para los scriptlets. Justo a continuacin, la lnea <%! int count=1; %> es una declaracin; la admiracin (!) 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 pgina. La declaracin se ejecutar la primera vez que se llame a la pgina, y se volver a ejecutar cada vez que se recompile la pgina (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 dems, la declaracin es una declaracin normal en Java; se pueden incluir tantas declaraciones como se quieran, no necesariamente al principio de la pgina. A continuacin vienen una serie de elementos HTML, hasta la lnea 7, donde se encuentra la orden <%= count++ %>. Todo lo que comience por <%= es una expresin JSP; el efecto
que tiene es la evaluacin de la expresin y la impresin del resultado. En este caso, se ejecuta la expresin y luego se imprime el valor, que es lo que hace el operador postincremento ++. Las expresiones en JSP pueden contener slo expresiones Java que devuelvan un valor, y no hace falta que se terminen con ;, como en el caso de las declaraciones. A continuacin se encuentra una combinacin de cdigo 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 cdigo Java est mezclado con el texto; en este caso, se incluira condicionalmente un texto u otro en la pgina de salida. Se podra hacer usando slo Java, de esta forma
<% if (count == 2) System.out.println('vez') } else { System.out.println('veces') } %>
Sin embargo, de esta forma, se pueden incluir ms fcilmente 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 lnea anterior. Si no queremos tomarnos toda la molestia de meterlo en el contnedor de servlets, podemos intentar compilarlo antes, para ver si hay algn 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 (versin 4):
djasper4 jspc hola.jsp
(aunque en el RPM de la versin 4.0.2 no funciona correctamente, creo...). Si todo va bien, se genera un fichero hola.java que, sera el que, compilado, dara el servlet; de hecho, este fichero se podra compilar y ponerse como servlet. Esta compilacin 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$jsp.java:90: 'catch' without 'try'. } catch (Throwable t) { ^
tras explicar el tipo, el mensaje y la descripcin. En realidad, este mensaje no tiene nada que ver con el error, pero es lo ms que se puede pedir, teniendo en cuenta que tenemos varias fases de compilacin. A lo que hay que prestarle atencin es a la ltima lnea, la que dice que se esperaba un }; como el cierre de llave est fuera de una etiqueta JSP, el intrprete no lo entiende. Sin embargo, si cometemos un error de sintaxis Java, la cosa estar un poco ms 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$jsp.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$jsp.java:83: ';' expected. } ese {
Como los errores no son muy informativos, muchas veces no queda otro remedio que leer bien leido el cdigo 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 algn servidor gratuito o en un servidor propio
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 comn
de acuerdo con ello (aunque siempre hay un asara 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 tambin dentro de la pgina (resultado0.jsp; y en accin 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>
El JSP es un poco extenso, sobre todo por el cdigo Java insertado. Este cdigo crea una clase llama Partido, que consta de los dos equipos que juegan, en casa y fuera, y del pronstico. El pronstico 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 pronsticos se pueden combinar (son las llamadas apuestas mltiples), de forma que un posible resultado a un partido puede ser X, 12 o incluso 1X2. La clase se compone de tres pares de mtodos, para establecer el valor (set) de una variable, y para devolver (get) el valor de la misma. A continuacin, se crea una instancia de la clase llamando a new; el objeto estePartido contendr el valor de la variable, y lo compartirn todas las llamadas al JSP. No es que sirva de mucho la comparticin, pero lo hemos dejado as. Unas lneas ms abajo se usa la etiqueta jsp:include, nuestra primera etiqueta JSP. Es una orden especfica de JSP, que en el servidor, antes de crearse la respuesta que se enve 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 pgina. Esto se puede hacer tambin 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 compilacin, mientras que jsp:include acta en tiempo de ejecucin. En este caso, se incluye una pequea cabecera comn 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 mtodos set, para despus recuperarlos dentro de una tabla, usando los mtodos get; el resultado del array booleano que devuelve getPronostico se tiene que formatear para convertirse en 1X2 En realidad, para lo que hemos hecho, podamos 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 estn definidos por un estndar 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 mtodos set (para cambiar su valor) y get para recuperar su valor; los mtodos set se llaman con un slo argumento del mismo tipo que la variable de instancia, y los mtodos get devuelven un objeto del tipo de la variable de instancia, sin tomar ningn argumento. No todos los mtodos set tienen que corresponder a una variable de instancia, ni tampoco los get; pero todos los mtodos 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 {
Los beans se pueden usar fcilmente desde los JSPs, usando etiquetas. El JSP anterior se puede poner de la forma siguiente, usando beans (resultado.jsp; el resultado en accin es prcticamente 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="Bara" /> <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 WEBINF/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 tendrn que ir a ese directorio. Los JARs irn tambin dentro de su directorio correspondiente, as como otros ficheros que no se destinan directamente a servirse al pblico. El JSP usa la orden en tiempo de compilacin explicada anteriormente para importar la habichuela dentro del contexto de la pgina. 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 usarn a travs de los mtodos 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 mayscula y se le precede con get o set para hallar el mtodo de la clase al que hay que llamar. Las lneas 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 mtodo sin correspondencia con ninguna variable de instancia; al JSP le da exactament igual, y llama al mtodo correspondiente. Como los errores no son muy informativos, muchas veces no queda otro remedio que leer bien leido el cdigo 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 seccin Acceso a objetos 5 Pginas dinmicas. implcitos Contenido dinmico Como para hacer pginas estticas, ya tenemos el HTML Excepciones propiamente dicho, vamos a meter un poco de dinamismo en las pginas, permitiendo que se modifique la pgina segn cmo se la llame. Ms adelante veremos cmo hacer que el usuario introduzca esos datos directamente. Para empezar, haremos que la pgina vare dependiendo de la forma cmo 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 dinmico</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 tomndolas de los argumentos con los que se llama el JSP; si lo llamamos de la forma siguiente
http://localhost:8080/jmerelo/resultadoDyn.jsp?juegaEnCasa=Osasuna&juegaF uera=Villareal&pronosticoAsString=X; se llamarn 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 parmetros que se pasan al JSP, estamos utilizando en realidad un objeto implcito 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 slo vara unas lneas 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 implcito request, llamando a su mtodo getParameter para obtener el valor del parmetro de llamada pronosticoAsString. Este objeto tiene los mismos mtodos que el equivalente de servlets, as que no nos extendemos ms en l. Los ms tiles son el anterior, getParameterNames y getParameterValues; otros, tales como getCookies, se usarn para obtener las cookies del cliente. En este caso, se incluirn en la salida diferentes cadenas dependiendo del valor del pronstico; si es un resultado mltiple, no se incluir nada. Hay otros objetos implcitos; probablemente los ms usados sean session, que maneja las variables de sesin, y application, con mtodos relativos al contexto dnde se est ejecutando el servlet al que corresponde el JSP. Qu puede ocurrir si alguno de los parmetros pasados tiene un valor invlido? Por ejemplo, se podan validar que los equipos correspondieran a la misma divisin, o que los pronsticos estn siempre compuestos de 1, equis o doses; hasta el momento, no se hace ningn tipo de comprobacin. Para ello, tendremos que modificar ligeramente el bean, haciendo que el mtodo setPronosticoAsString tire una excepcin si se encuentra con un carcter invlido en la cadena que se le pasa. Despus de cambiarle el nombre a la clase ( quiniela/PartidoValidado.java):
public void setPronosticoAsString(String _newVal) throws RuntimeException{ if (_newVal.length() > 3) throw new RuntimeException ( "Pronstico ms largo de la cuenta" ); if (_newVal.length() == 0) throw new RuntimeException ( "No hay pronstico" ); for ( int j = 0; j < _newVal.length(); j ++ ) { if ( _newVal.charAt(j) != '1' && _newVal.charAt(j) != 'X' && _newVal.charAt(j) != '2' ) { throw new RuntimeException ( "Carcter raro en cadena:"+ _newVal.charAt(j) + " en la posicin " + j ); } } for ( int i=0; i < 3; i++ ) { if ( _newVal.indexOf(this.unoequisdos.charAt(i)) >= 0 ) {
Con respecto a la versin anterior, se han aadido una serie de comprobaciones de longitud excesiva, demasiado pequea, o si hay algn carcter que no sea 1X2. Capturar la excepcin en un programa en Java es fcil (con las sentencias try y catch), pero, en un JSP nos encontraremos algo as:
java.lang.reflect.InvocationTargetException: java.lang.RuntimeException: Pronstico ms largo de la cuenta at quiniela.PartidoValidado.setPronosticoAsString(PartidoValidado.jav a:31)
Para ello se usan las pginas de error, que se llaman en caso de que se haya producido una excepcin; es ms o menos lgico que no se traten las excepciones dentro de la misma pgina, porque, en algunos casos, pueden producirse antes incluso de que el cdigo haya sido generado. Para usar la pgina 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 pgina de error, y se asigna un atributo a la peticin, que almacenar el URI de la peticicin, es decir, el camino con el que se la ha llamado. El cdigo de la pgina 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 pgina <%= request.getAttribute("paginaOrigen") %> <%@ include file ="pie.jsp" %>
Lo ms importante es la primera lnea: la pgina se declara a s misma como una pgina que responde a los errores, lo cual permite que se cree el objeto implcito exception. Ese objeto se usa ms adelante para imprimir el mensaje que se ha producido (aunque no siempre funciona). Tambin se recupera un atributo del objeto implcito request, que haba sido puesto por la pgina que ha producido el error, para que se sepa de dnde procede el error. Cuando se produzca alguna entrada errnea, por ejemplo,
pronosticoAsString=123,
se producir una excepcin en el objeto PartidoValidado, que se propagar al JSP que la contiene, que a su vez llamar a esta pgina de error . Ejercicios 4 1. Cambiar la encuesta para que tome los resultados de los parmetros que se le pasen al JSP . 2. Cambiar la EncuestaBean para que detecte errores (tales como una respuesta incorrecta), y levante una excepcin; crear una pgina de error que capture esa excepcin y la muestre. Contenido de esta seccin Formularios 6 Procesamiento de formularios Combinacin de elementos JSP Ya est bien de tanto objeto implcito y tanta gaita, vamos a mbitos ir directamente al turrn de procesar formularios como Dios Taglibs manda. Vamos a tratar de hacer una pgina JSP que cree y a la vez procese el formulario; de esta forma es ms fcil de mantener. El formulario nos permitir rellenar la quiniela sin hacer nada en concreto con ella, slo presentarla. En la prctica, habra 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 cdigo 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.dat" /> <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>Pronstico</th><th>Pronstico 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 empezar, hemos creado un nuevo bean que contiene un Para quien no haya trabajado con vector de partidos, llamado Quiniela; este bean ser el que formularios (ver por ejemplo este usemos en la pgina; en general, es una buena idea reflejar tutorial de formularios o bien este tutorial de HTML, que incluye la estructura de una pgina en un bean, o viceversa. En el tambin formularios) caso anterior usbamos 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 ningn mtodo con dos argumentos, por lo que tenemos que establecer un cursor de partido que indique sobre qu partido van a actuar los mtodos que ponen o extraen valores de la clase El objeto que va a contener la quiniela se declara en las primeras lneas, mediante el tag <jsp:useBean>. A continuacin se le pasa el fichero quiniela.dat, que contiene los datos de una quiniela (de primera divisin universal especial, como se puede comprobar). A continuacin, despus 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 parmetro (pronostico + el ndice), se usa esa cadena para colocar el cursor (%lt;jsp:setProperty name='estaQuiniela' property='numPartido' value="<%= i %>" />) y se asigna el pronstico 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 lneas se presentan los resultados que se han introducido lado a lado con una serie de cuadros de texto que permiten cambiar el pronstico.
Este cdigo 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 cdigo de correccin de errores, porque siempre se puede modificar a mano la peticin al servidor. Simplemente, se le evitan problemas al usuario. Eso se hace en la siguiente versin 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'>Pronstico</th><th rowspan='2'>Pronstico 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 parmetro, se usa getParameterValues, que devuelve un array con todos los valores que tiene un parmetro; en este caso, cada grupo de 3 botones usa el mismo nombre de elemento del formulario, por eso cada parmetro tendr tantos elementos como botoncitos se hayan rellenado. En todo caso, se pegan los parmetros en una sola cadena, que se usa para asignarle un valor al pronstico. En cuanto al formulario, en este caso tenemos que usar el pronstico como un array de valores booleanos (en vez de una cadena como hacamos anteriormente), porque nos conviene ms a la hora de poner el valor por defecto a los botones. Usamos tambin un mtodo de clase de Java, para pasar de un ndice de 0 a 2 al smbolo correspondiente (1, X o 2). Pero claro, lo interesante no es slo presentar los datos del formulario, sino agregarlos en unas estadsticas para toda la oficina (y de camino, fastidiar al asara mostrndole que su pronstico no lo comparte nadie) y presentarlos en un grfico 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 aplicacin, indicndolo con scope='application' . Eso significa que va a poder ser "visto" por todos los dems servlets y JSPs del servidor; sera algo as como una variable del servidor. Esto lo vamos a usar para poder compartir informacin entre diferentes invocaciones y diferentes JSPs. Hay cuatro mbitos diferentes en las variables usadas en JSPs y servlets:
el mbito de pgina: objetos que slo estn accesibles durante la ejecucin del cdigo de una pgina peticin: objetos compartidos entre las diferentes pginas que manejan una peticin, por ejemplo, una pgina y la que maneje errores de la primera, o una pgina y otra a la que se pasa control con la orden jsp:forward sesin; objetos compartidos entre las diferentes pginas que se llamen a travs de una sesin, y, por ltimo
. Este ltimo mbito es el que usamos precisamente en esta pgina. Para entendernos, seran como una especie de objetos persistentes, que estarn ah hasta que rearranquemos el servidor. Y precisamente eso es lo que vamos a hacer, usarlos para ver esas estadsticas 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 Estadsticas de la quiniela</title> </head> <%@ include file ="cabecera.jsp" %> <h1>Ver Estadsticas de la quiniela</h1> <table border> <tr><th>Partido</th><th colspan='2'>Estadsticas</th> </tr> <tr> <td>Alcorcn - 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" %>
Las nove dade s de este nuev o fich ero emp ieza n pron to: en la prim era lnea. Los grficos no es algo que se pueda hacer con JSPs as, a pelo, as que usamos una librera de etiquetas, una tag library. En este caso se trata de la librera barchart, una taglib
para hacer grficos de barras horizontales y verticales. Instalarla es fcil: hacen falta dos ficheros: el archivo de clases de java, .jar, y una descripcin de las etiquetas y su correspondencia con mtodos 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. Tambin pueden ir al mismo directorio donde est el fichero correspondiente, pero ser ms complicado de usar desde otros JSPs. La taglib esta tambin est disponible en iSavvix, entre otras muchas Las taglibs son simplemente un cambio de interface con respecto al cdigo Java normal; te ahorran insertar cdigo dentro de las pginas, y son, en general, ms fciles de mantener, porque, en el ms puro estilo OO, encapsulan su lgica y el que las usa no tiene que preocuparse por cmo hacen lo que hacen, slo 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 slo permite cinco datos simultneos, as que tendremos que hacer un grfico 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" ; adems, 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 estadsticas sobre las respuestas contestadas 2. Usar una librera de etiquetas que incluya bucles, y convertir algn 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 sesin.
La tecnologa Java para la creacin de pginas web con programacin en el servidor. Por Miguel Angel Alvarez
Atencin: Contenido exclusivo de DesarrolloWeb.com. No reproducir. Copyright.
JSP es un acrnimo de Java Server Pages, que en castellano vendra a decir algo como Pginas de Servidor Java. Es, pues, una tecnologa orientada a crear pginas web con programacin en Java. Bibliografa: Esta descripcin de JSP est extrada de un PDF en ingls muy completo que introduce la tecnologa, que se puede encontrar el la pgina corporativa de Java de Sun Microsystems, en su seccin de aprendizaje online. A su vez, dicho manual proviene del portal Java jGuru. jGuru: Introduction to JavaServer Pages technology Con JSP podemos crear aplicaciones web que se ejecuten en variados servidores web, de mltiples plataformas, ya que Java es en esencia un lenguaje multiplataforma. Las pginas JSP estn compuestas de cdigo HTML/XML mezclado con etiquetas especiales para programar scripts de servidor en sintaxis Java. Por tanto, las JSP podremos escribirlas con nuestro editor HTML/XML habitual. Motor JSP El motor de las pginas JSP est basado en los servlets de Java -programas en Java destinados a ejecutarse en el servidor-, aunque el nmero de desarrolladores que pueden afrontar la programacin de JSP es mucho mayor, dado que resulta mucho ms sencillo aprender que los servlets. En JSP creamos pginas de manera parecida a como se crean en ASP o PHP -otras dos tecnologas de servidor-. Generamos archivos con extensin .jsp que incluyen, dentro de la estructura de etiquetas HTML, las sentencias Java a ejecutar en el servidor. Antes de que sean funcionales los archivos, el motor JSP lleva a cabo una fase de traduccin de esa pgina en un servlet, implementado en un archivo class (Byte codes de Java). Esta fase de traduccin se lleva a cabo habitualmente cuando se recibe la primera solicitud de la pgina .jsp, aunque existe la opcin de precompilar en cdigo para evitar ese tiempo de espera la primera vez que un cliente solicita la pgina. Ejemplo de pgina JSP En la imagen siguiente se puede ver un ejemplo extremadamente simple de una pgina JSP y el esquema de conversin de esa pgina en un servlet.
Prerequisitos Para aprender JSP, aparte de conocer HTML, ser necesario comprender y tener algo de experiencia en la programacin en Java, que es un lenguaje de programacin Orientado a Objetos por completo. Una vez conocida la programacin en Java se puede estudiar por encima el sistema de Servlets, lo que nos dar una mejor idea del funcionamiento interno del motor JSP. Para aprender Java podemos consultar algunos enlaces del correspondiente directorio de nuestro buscador de enlaces. Adems, necesitaremos descargar e instalar Tomcat, el contenedor de servlets usado en la referencia oficial de implementacin de JSP. Podemos acceder a un ejercicio para aprender a realizar esta instalacin, disponible tambin en la referencia de aprendizaje de la pgina de Java. Referencias JSP