Sei sulla pagina 1di 250

Unidad de Aprendizaje 1

INTRODUCCIN A JAVA EE

NDICE
1.1 Introduccin ..........................................................................3
1.1.1 Java Card .......................................................................... 3
1.1.2 Java Micro Edition (Java ME) ......................................... 4
1.1.3 Java Standard Edition (Java SE).................................... 4
1.1.4 Java Enterprise Edition (Java EE) .................................. 4
1.2El modelo de aplicacin Java EE........................................5
1.2.1 Componentes Java EE .................................................... 6
1.2.2 Contenedores Java EE .................................................... 7
1.2.3 Servicios Java EE ............................................................. 8
1.3El diseo de aplicaciones Java EE .....................................8
1.4Las especificaciones Java EE...........................................10
1.5El ensamblado y despliegue de aplicaciones Java EE ..13
1.6El Servidor de Aplicaciones Java EE................................15
PARA RECORDAR ....................................................................18

MDULO A Unidad 1: Introduccin a Java EE

1.1

Introduccin

Debido a la naturaleza del lenguaje Java: portable, seguro, multithread, etc, est siendo
utilizado en multitud de mbitos y tecnologas, desde el chip de una tarjeta de crdito hasta un
servidor de la ms alta gama.
Evidentemente,

estos

distintos

mbitos

entornos,

tienen

unas

caractersticas

peculiaridades muy distintas entre s. Por ejemplo, la cantidad de memoria disponible en el


chip de una tarjeta de crdito y la de un servidor es muy distinta, por lo que habr que tenerlo
en cuenta a la hora de desarrollar las aplicaciones.
Es por ello que existen distintas plataformas Java, dependiendo del mbito en el que se vaya a
trabajar.
Son las siguientes:

Java Card.

Java Micro Edition (Java ME).

Java Standard Edition (Java SE).

Java Enterprise Edition (Java EE).

Podemos verlas resumidas en el siguiente grfico:

1.1.1 Java Card


La plataforma Java Card define las APIs y requerimientos necesarios para poder ejecutar
aplicaciones Java en los chips de las tarjetas. Debido a las mnimas prestaciones del entorno
de ejecucin contiene el API ms escueto.
El estudio de esta plataforma no es el objetivo de este curso, pero si el alumno quiere
profundizar en este tema podr encontrar ms informacin en la siguiente URL:
http://www.oracle.com/technetwork/java/javame/javacard/overview/getstarted/index.html

1.1.2 Java Micro Edition (Java ME)


La plataforma Java Micro Edition define las APIs y requerimientos necesarios para poder
ejecutar aplicaciones Java en dispositivos embebidos. Debido a la gran diversidad de estos
dispositivos, desde telfonos mviles o buscas con pocas prestaciones hasta televisores o
automviles mucho ms potentes, se definieron distintas configuraciones con ms o menos
APIs y por tanto, posibilidades.
Por defecto existen estos dos:
CLDC (Connected Limited Device Configuration): Define las APIs y la JVM
(denominada KVM) para dispositivos con muy pocas prestaciones.
CDC (Connected Device Configuration): Define las APIs para dispositivos con pocas
prestaciones pero conectados a la red. No requiere una JVM especial.
El estudio de esta plataforma no es el objetivo de este curso, pero si el alumno quiere
profundizar en este tema podr encontrar ms informacin en la siguiente URL:
http://www.oracle.com/technetwork/java/javame/index.html

1.1.3 Java Standard Edition (Java SE)


La plataforma Java Standard Edition (Java SE) define las APIs y requerimientos necesarios
para poder ejecutar aplicaciones Java de escritorio en ordenadores personales o porttiles.
El estudio de esta plataforma no es el objetivo de este curso, pero si el alumno quiere
profundizar en este tema, Aula Mentor cuenta con otros dos cursos que la cubren:
Programacin en Java Inicial
Programacin en Java Avanzado
Puedes consultar la informacin de estos cursos en www.aulamentor.es, en el apartado
Cursos Programacin.

1.1.4 Java Enterprise Edition (Java EE)


La plataforma Java Enterprise Edition (Java EE) define las APIs y requerimientos necesarios
para poder ejecutar aplicaciones Java servidoras, con todo lo que ello supone: clienteservidor, multiusuario, transaccionalidad, escalabilidad, etcen definitiva, caractersticas que
no eran importantes o imprescindibles en aplicaciones de escritorio.
Se apoya en la plataforma Java SE, por lo que es imprescindible conocer y dominar dicha
plataforma antes de aventurarse en esta otra. Utiliza la misma Mquina Virtual Java (JVM).
Este curso se centra precisamente en esta plataforma, aunque no en su totalidad. Como
veremos un poco ms adelante, las aplicaciones Java EE pueden dividirse en varias capas y
este curso se centra la denominada capa web o de presentacin.
La plataforma Java Enterprise Edition ha pasado por distintas nomenclaturas y versiones a lo
largo de su vida, de manera que hubo momentos en el tiempo en el que se denomin Java 2
y luego simplemente Java. Las versiones tambin han sufrido modificaciones, comenzando a
numerarse como 1.2, 1.3 para a posteriori pasar a numerarse como 5.0, 6.0
Actualmente estamos en la versin 6.0, pero en su totalidad han existido:

Java 2 EE 1.2
4

MDULO A Unidad 1: Introduccin a Java EE


Java 2 EE 1.3
Java 2 EE 1.4
Java EE 5.0
Java EE 6.0
La definicin de esta y las otras plataformas se realiza mediante un proceso colaborativo
entre distintas empresas denominado Java Community Process (JCP). Para cada plataforma,
API, funcionalidad se crea lo que se denomina como Java Specification Request (JSR)
donde se sientan las bases y especificaciones de dicha plataforma, API o funcionalidad.
En concreto la discusin y definicin de la futura plataforma Java EE 7.0 se puede seguir en
la siguiente URL: http://www.jcp.org/en/jsr/detail?id=342

1.2

El modelo de aplicacin Java EE

El modelo de aplicaciones Java EE define una arquitectura para implementar servicios como
aplicaciones multicapa que aseguren la escalabilidad, accesibilidad y facilidad de gestin
necesarias en un mbito empresarial.
El modelo divide el trabajo a realizar en la implementacin en dos partes:

La lgica de presentacin y de negocio a implementar por el desarrollador.

Los servicios estndar que ofrece la plataforma Java EE.

El desarrollador puede apoyarse en los servicios ofrecidos por la plataforma Java EE en vez de
reinventar la rueda una y otra vez, facilitndole as el concentrarse nicamente en la lgica
especfica de su aplicacin.
La plataforma Java EE utiliza un modelo de programacin distribuido en distintas capas. La
lgica de la aplicacin se divide en distintos componentes dependiendo de su funcionalidad, y
estos son desplegados en las distintas capas dependiendo de a cul pertenecen.
Las distintas capas son:

Capa cliente (Client Tier): responsable de la interaccin con el usuario.

Capa web (Web Tier): responsable del control de la aplicacin y en ocasiones tambin
de la interaccin con el usuario.

Capa de negocio (Business Tier): responsable de la lgica de la aplicacin


propiamente dicha.

Capa de datos (EIS Tier): responsable de la persistencia de datos y/o lgica


especializada (conocida con el nombre de EIS: Enterprise Information System, o
Sistema

de

Informacin

Empresarial).

Por

ejemplo

ERPs,

BBDD,

Motores

Transaccionales (CICS, IMS, Tuxedo).


A continuacin mostramos este concepto de multicapa en un diagrama:

Es muy importante tener en cuenta, que esta divisin es puramente lgica y no fsica. Es decir,
fsicamente cada capa no tendr por qu estar en mquinas independientes, sino que podrn
compartir hardware. Por ejemplo, veremos que lo normal ser que el entorno de desarrollo que
montaremos para resolver las distintas actividades de este curso tendr todas las capas
fsicamente en la misma mquina.
Adicionalmente al tema multicapa, el modelo de aplicacin Java EE define otros tres
conceptos claves para entender la plataforma:

Componentes: Unidades de software que forman o componen la aplicacin.

Contenedores: Entorno de ejecucin donde se ejecutan los componentes.

Servicios: Funcionalidades estndar que todo contenedor debe proveer a los


componentes.

Veamos qu son y en qu consisten cada uno de estos conceptos.

1.2.1 Componentes Java EE


Una aplicacin Java EE est compuesta de componentes. Un componente Java EE es una
unidad de software funcional auto contenida que se ensambla como parte de una aplicacin
Java EE y que puede interactuar con otros componentes.
Las especificaciones Java EE definen lo siguientes tipos de componentes:

Componentes cliente: son aplicaciones Java SE (AWT/Swing, Applets) o un navegador


web (Firefox, Chrome, IExplorer). Se despliegan en la capa cliente.

MDULO A Unidad 1: Introduccin a Java EE

Componentes web: son Java Servlets, JavaServer Pages (JSP) o JavaServer Faces
(JSF). Se despliegan en la capa web.

Componentes de negocio: Enterprise JavaBeans (EJB). Se despliegan en la capa de


negocio.

1.2.2 Contenedores Java EE


Normalmente el desarrollo de una aplicacin empresarial es muy complicado dado que el
desarrollador tiene que tener en cuenta temas muy importantes como la gestin multiusuario,
la gestin de la transaccionalidad, la gestin de la seguridad, la comparticin de recursos,
etc
El modelo de programacin de la plataforma Java EE facilita enormemente esta tarea con la
definicin de los contenedores Java EE. Estos contenedores ofrecen al desarrollador una
serie de servicios sobre los que se puede apoyar permitindole centrarse en el desarrollo de
la lgica de negocio de la aplicacin propiamente dicha.
Dependiendo del tipo de contenedor, ofrecer unos servicios u otros, y permitir desplegar
en l un tipo de componente u otro. Los tipos de contenedores Java EE son:
Contenedor cliente (Application Client Container o Applet Container).
Contenedor web (Web Container).
Contenedor de negocio o de EJBs (EJB Container).
Como podemos ver, cada tipo de contenedor corresponde con una de las capas definidas, a
excepcin de la capa de datos que est implementada por otro tipo de productos (ya
mencionados anteriormente) ajenos a la plataforma Java EE.
En el siguiente diagrama, podemos observar la relacin entre los distintos tipos de
contenedores Java EE:

1.2.3 Servicios Java EE


Las especificaciones Java EE, definen una serie de funcionalidades que los distintos tipos de
contenedores debern implementar y ofrecer a los desarrolladores de aplicaciones Java EE.
Existen multitud de servicios, pero simplemente destacaremos algunos:
De directorio: para la indexacin y bsqueda de componentes y recursos.
De despliegue: para facilitar la descripcin y personalizacin de componentes a la hora
de su instalacin.
De transaccionalidad: para poder ejecutar distintas acciones en una misma unidad
transaccional.
De seguridad: para poder autenticar y autorizar a los usuarios de una aplicacin.
De acceso a datos: para facilitar el acceso a las Bases de Datos.
De conectividad: para facilitar el acceso a los distintos Sistemas de Informacin
Empresarial (EIS).
De mensajera: para poder comunicarse con otros componentes, aplicaciones o EISs.

1.3

El diseo de aplicaciones Java EE

Todos los informticos saben, que antes de ponerse a programar hay una fase muy importante
de anlisis y de diseo donde se estudia y define la solucin. Para ello, contamos con el
lenguaje UML (Unified Modeling Language) que define una serie de diagramas y notaciones
para poder plasmar estos anlisis y diseos.
Nota: El lenguaje UML no es objeto de este curso pero se cubre con cierta profundidad en el
curso de Aula Mentor: Programacin en Java Inicial.
Adicionalmente, existe el concepto de Patrones de Diseo, que son un conjunto de soluciones
(o diseos) a los problemas ms comunes en la programacin de aplicaciones, que han
demostrado ser tiles y eficientes en la resolucin de dichos problemas. Su existencia, permite
poder reutilizar y aplicar soluciones existentes, y no estar reinventando la rueda
constantemente.
Pues bien, existe un conjunto importante de estos patrones de diseo muy relacionados con el
desarrollo de aplicaciones Java EE. A lo largo del curso iremos viendo algunos, pero si el
alumno quiere profundizar en este tema tiene el catlogo completo en las Blue Prints de Java
EE:
http://www.oracle.com/technetwork/java/catalog-137601.html

MDULO A Unidad 1: Introduccin a Java EE


En este captulo de introduccin a Java EE, vamos a hablar de uno que ataca directamente
las problemticas derivadas del modelo de una aplicacin Java EE multicapa. Es conocido con
el nombre de: Modelo-Vista-Controlador (MVC).
Las aplicaciones que manejan acceso a datos, gestionan distintas presentaciones y tienen
lgica de negocio compleja, suelen sufrir un problema serio a la hora de mantenerlas debido a
interdependencias entre todos los componentes. Dichas interdependencias tambin dificultan
la reutilizacin de cdigo, obligando a rescribir ms veces de las deseadas una lgica muy
parecida.
El patrn de diseo MVC resuelve estos problemas desacoplando el acceso a datos de la
lgica de negocio y esta de la presentacin. De esta forma, se podr reutilizar un acceso
desde distintas funcionalidades, o reutilizar la misma funcionalidad desde distintos tipos de
presentacin, etc facilitando tambin el mantenimiento posterior:

El Modelo (Model): Representa los datos y cualquier lgica de negocio relacionada con
ellos.

La Vista (View): renderiza el contenido de los modelos dependiendo de la tipologa de


cliente (navegador web, telfono mvil, etc), permitiendo su visualizacin.

El Controlador (Controller): define el comportamiento general de la aplicacin


coordinando a las otras dos partes (Modelo y Vista).

Veamos el patrn de diseo en un diagrama:

Pues bien, los distintos tipos de componentes que hemos introducido en el apartado del
modelo de aplicacin Java EE, encajan perfectamente en este diseo:
Modelo: Enterprise JavaBeans, POJOs (Plain Old Java Objects).
Vista: JavaServer Pages (JSP), JavaServer Faces (JSF).
Controlador: Java Servlets.
Un ejemplo del flujo de una aplicacin Java EE sera algo as:
1. El cliente, por ejemplo un navegador, solicitar una funcionalidad desde el interface
visual (Vista).
2. Dicha peticin entrar a travs de un Java Servlet (Controlador).
3. Dicho Java Servlet, analizar qu se est pidiendo, qu informacin adicional aporta y
decidir que Enterprise JavaBean o POJO (Modelo) cubre dicha peticin.
4. Lo invocar, y tras recibir un resultado, decidir qu JavaServer Page (JSP) muestra
dicho resultado al cliente (Vista).
5. El resultado ser devuelto y mostrado.
Y visualmente:

Evidentemente, las aplicaciones se pueden desarrollar sin tener en cuenta estos patrones de
diseo, pero est demostrado sobradamente en el mercado, el aumento de productividad y
mejora del mantenimiento con su uso.
A lo largo del curso iremos insistiendo en este punto y detallando y practicando tanto este
patrn como otros.

1.4

Las especificaciones Java EE

Las especificaciones Java EE son el conjunto de las definiciones detalladas de los conceptos
que forman parte de la plataforma Java EE: componentes, contenedores y servicios.
10

MDULO A Unidad 1: Introduccin a Java EE


No entraremos en el detalle de cada una. A lo largo del curso, iremos desgranando aquellas
especificaciones relacionadas con la programacin web.
En concreto, las especificaciones Java EE 6.0 (ltima versin en el momento de la redaccin
de este manual) estn compuestas por las siguientes definiciones (en negrita las que
cubriremos en el curso):

Java API for RESTful Web Services (JAX-RS) 1.1

Implementing Enterprise Web Services 1.3

Java API for XML-Based Web Services (JAX-WS) 2.2

Java Architecture for XML Binding (JAXB) 2.2

Web Services Metadata for the Java Platform

Java API for XML-Based RPC (JAX-RPC) 1.1

Java APIs for XML Messaging 1.3

Java API for XML Registries (JAXR) 1.0

Java Servlet 3.0

JavaServer Faces 2.0

JavaServer Pages 2.2/Expression Language 2.2

Standard Tag Library for JavaServer Pages (JSTL) 1.2

Debugging Support for Other Languages 1.0

Contexts and Dependency Injection for Java (Web Beans 1.0)

Dependency Injection for Java 1.0

Bean Validation 1.0

Enterprise JavaBeans 3.1 (incluye Interceptors 1.1)

Java EE Connector Architecture 1.6

Java Persistence 2.0

Common Annotations for the Java Platform 1.1

Java Message Service API 1.1

Java Transaction API (JTA) 1.1

JavaMail 1.4

Java Authentication Service Provider Interface for Java Authorization Contract for
Containers 1.3

Java EE Application Deployment 1.2


11

J2EE Management 1.1

Dado que la plataforma Java EE extiende la Java SE, existen especificaciones Java SE
incluidas en Java EE:

Java API for XML Processing (JAXP) 1.3

Java Database Connectivity 4.0

Java Management Extensions (JMX) 2.0

JavaBeans Activation Framework (JAF) 1.1

Streaming API for XML (StAX) 1.0

Java Naming and Directory Interface (JNDI) 1.2

Como ya hemos comentado, la plataforma Java EE es un tema muy extenso que toca gran
cantidad de mbitos y tecnologas. Nosotros en este curso titulado Programacin Web nos
centraremos exclusivamente en aquellas especificaciones relacionadas con la presentacin y
el acceso a Bases de Datos.
Existe documentacin on-line de todas estas especificaciones o APIs que sern de enorme
utilidad a la hora de desarrollar aplicaciones Java EE:
http://download.oracle.com/javaee/6/api/

12

MDULO A Unidad 1: Introduccin a Java EE

1.5

El ensamblado y despliegue de aplicaciones Java EE

Una aplicacin Java EE est formada por un empaquetamiento de una o varias unidades
conocidas con el nombre de mdulos. Estos mdulos contienen a su vez:
Uno o varios componentes (Java Servlets, Enterprise JavaBeans (EJB)).
Un descriptor de despliegue que describe el contenido y caractersticas del mdulo
(desde la versin 5.0 estos descriptores son opcionales, ya que el propio cdigo
puede ser auto descriptivo mediante el uso de anotaciones).
Existen distintos tipos de mdulos dependiendo de su contenido y el contenedor donde se
vaya a ejecutar. Los distintos mdulos van empaquetados en un fichero JAR (Java ARchive).
No obstante, la extensin de dicho fichero depender del tipo de mdulo:
Mdulo Web (Web Module): contiene normalmente Java Servlets, JavaServer Pages
(JSP), JavaServer Faces (JSF), contenidos estticos como imgenes, HTMLs, CSSs
La extensin del fichero empaquetado ser WAR (Web ARchive).
Modulo de EJBs (EJB Module): como su nombre indica, contiene Enterprise
JavaBeans (EJB). La extensin del fichero empaquetado es la de por defecto, JAR
(Java ARchive).
Modulo cliente (Application Client Module): contiene el cdigo de la aplicacin cliente.
La extensin del fichero empaquetado es la de por defecto, JAR (Java ARchive).
Modulo

Adaptador

(Resource

Adapter

Module):

contiene un conector para

comunicarse con un Sistema de Informacin Empresarial (EIS). La extensin del


fichero empaquetado ser RAR (Resource ARchive).
La aplicacin Java EE a su vez, tambin es un empaquetado de los distintos mdulos que la
forman. La extensin del fichero empaquetado ser EAR (Enterprise ARchive).
Una aplicacin Java EE no tiene por qu contener mdulos de todos los tipos, lo que si es
necesario, es que tenga como mnimo uno independientemente del tipo.
Grficamente, la estructura de una aplicacin Java EE empaquetada sera la siguiente,
partiendo desde la raz del EAR (Assembly Root):

13

El descriptor de despliegue de una aplicacin Java EE es un fichero XML llamado


application.xml que reside en un directorio denominado META-INF.
Como ya hemos mencionado, desde la versin 5.0 de las especificaciones Java EE, este
descriptor de despliegue es opcional si se han usado anotaciones en el cdigo. No obstante,
no est mal seguir utilizndolos para que los administradores de los sistemas de una manera
legible y sencilla puedan entender el contenido y las caractersticas de la aplicacin.
Un ejemplo de descriptor de despliegue sera:
<?xmlversion="1.0"encoding="UTF8"?>
<applicationxmlns:xsi="http://www.w3.org/2001/XMLSchemainstance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:application="http://java.sun.com/xml/ns/javaee/application_5.xsd
"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/application_6.xsd"id="PruebaEAR"
version="6">
<module>
<connector>PruebaConnector.rar</connector>
</module>
<module>
<java>PruebaClient.jar</java>
</module>
<module>
<ejb>PruebaEJB.jar</ejb>
</module>
<module>
<web>
<weburi>PruebaWeb.war</weburi>
<contextroot>PruebaWeb</contextroot>
</web>
</module>
</application>
Se trata de una aplicacin Java EE que contiene un mdulo de cada tipo. No hay que
preocuparse si no se entiende el contenido del fichero como tal, ya que de momento,
simplemente se trata de ver un ejemplo del concepto de descriptor de despliegue.

14

MDULO A Unidad 1: Introduccin a Java EE


Debido a que este curso es sobre programacin web, nos centraremos nicamente en los
mdulos web, aunque no est de ms conocer la existencia de otro tipo de mdulos.

1.6

El Servidor de Aplicaciones Java EE

Hasta aqu, todo han sido especificaciones, definiciones pero para poder ejecutar una
aplicacin Java EE necesitamos un entorno de ejecucin. Dicho entorno de ejecucin se
conoce con el nombre de Servidor de Aplicaciones.
Un Servidor de Aplicaciones por tanto, es un producto de software que implementa todas las
especificaciones Java EE. De manera que al desplegar o instalar una aplicacin Java EE en el
servidor, sabemos seguro que va a encontrarse con todos los contenedores y servicios
definidos por la especificacin y que seguramente utiliza y necesita la aplicacin.
Existe una batera de pruebas estndar que todo proveedor de Servidores de Aplicaciones
debe pasar satisfactoriamente para poder decir que es Java EE. Es lo que se conoce con el
nombre de JCK (java Compatibility Kit o Kit de Compatibilidad Java).
Gracias a la existencia del estndar Java EE, podemos tener la tranquilidad de que nuestra
aplicacin debe funcionar perfectamente en el Servidor de Aplicaciones de cualquier
proveedor, asegurndonos as que no debemos de trabajar con ninguno en concreto.
Existen multitud de Servidores de Aplicaciones en el mercado. Podramos categorizarlos de la
siguiente forma:
Gratuitos o de pago.
Certificados Java EE o no.
A continuacin comentamos algunos. No estn todos los que son, ni son todos los que estn,
pero si los ms usados y conocidos:
Apache Tomcat: Es gratuito de cdigo abierto. No cumple con el 100% de las
especificaciones Java EE por lo que no se puede decir que sea un Servidor de
Aplicaciones Java EE. Pero si que cubre algunas de las especificaciones relacionadas
con la programacin web que estudiamos en este curso: Java Servlet 3.0, JavaServer
Pages 2.2, Java Database Connectivity 4.0 y Java Naming and Directory Interface 1.2
Este es el Servidor de Aplicaciones que usaremos en este curso. En los Materiales de
Apoyo de la Mesa del Alumno, encontraris las instrucciones de descarga, instalacin
y configuracin del servidor.

URL: http://tomcat.apache.org
15

Jetty: Es gratuito y de cdigo abierto. Al igual que pasara con Apache Tomcat,
tampoco implementa el 100% de las especificaciones Java EE. Una vez ms, se
centra exclusivamente en algunas especificaciones web.

URL: http://jetty.codehaus.org/jetty/
WebSphere Application Server: Es de pago de la empresa IBM. Se trata de un Servidor
de Aplicaciones Java EE completo.

URL: http://www-01.ibm.com/software/webservers/appserv/was/

Apache Gernimo: Es gratuito y de cdigo abierto. Se trata de un Servidor de


Aplicaciones Java EE completo.

URL: http://geronimo.apache.org

Oracle Weblogic Server: Es de pago de la empresa Oracle. Se trata de un Servidor de


Aplicaciones Java EE completo.

16

MDULO A Unidad 1: Introduccin a Java EE


URL: http://www.oracle.com/us/products/middleware/application-server/

GlassFish: Es gratuito y de cdigo abierto. Se trata de un Servidor de Aplicaciones


Java EE completo.

URL: http://glassfish.java.net/

JBoss: Es gratuito y de cdigo abierto. Se trata de un Servidor de Aplicaciones Java


EE completo.

URL: http://www.jboss.org/jbossas

17

PARA RECORDAR

En esta unidad hemos visto la diferencia entre las distintas versiones de Java: Java
Card, Java Micro Edition, Java Standar Edition y Java Enterprise Edition (Java
EE).

Las aplicaciones Java EE, estn distribuidas en distintas capas para una mejor
organizacin funcional: capa cliente (para interactuar con el usuario), capa web
(para llevar el control de la aplicacin y a veces interactuar con el usuario), capa de
negocio (contiene la lgica del negocio como tal) y la capa de datos (contiene la
informacin de negocio).

A su vez la plataforma Java EE, para poder ejecutar las aplicaciones Java EE
multicapa, est formada por:
Componentes: Unidades de software que forman o componen la aplicacin
Contenedores: Entorno de ejecucin donde se ejecutan los componentes.
Servicios: Funcionalidades estndar que todo contenedor debe proveer a los
componentes.

Para poder disear aplicaciones Java EE, ya existen distintos patrones de diseo
muy extendidos que posibilitan la reutilizacin de los componentes y un mejor
mantenimiento de los mismos, como es el patrn Modelo-Vista-Controlador
(MVC).

Para que una aplicacin Java EE, pueda ejecutarse en un servidor Java EE, estos
deben de cumplir las especificaciones determinadas en una versin dada o al
menos aquellas necesarias para el tipo de aplicacin que se desea implementar.

Las aplicaciones Java EE (fichero EAR) estn formadas por al menos un mdulo de
los siguientes tipos: Mdulo Web (fichero WAR), Modulo de EJBs (fichero JAR),
Modulo cliente (fichero JAR), Modulo Adaptador (fichero RAR).

18

En el mercado existen una multitud de servidores de aplicaciones, pudiendo ser


clasificados por dos categoras:

Gratuitos o de pago.

Certificados Java EE o no.

19

20

Unidad de Aprendizaje 2

EL ENTORNO DE DESARROLLO

NDICE
2.1

Introduccin ................................................................... 23

2.2

Descarga, instalacin y configuracin del entorno de


desarrollo........................................................................ 24
2.2.1 Java Runtime Environment (JRE) .................................24
2.2.2 Eclipse IDE for Java EE Developers ............................29
2.2.3 Apache Tomcat...............................................................34

PARA RECORDAR.................................................................... 40

MDULO A Unidad 2: El Entorno de Desarrollo

2.1

Introduccin

Existen multitud de herramientas de desarrollo y ejecucin de aplicaciones Java EE. Muchas


de ellas son de pago, pero existen tambin gratuitas proporcionadas por la Comunidad Open
Source.
Aunque en condiciones normales, en el da a da de una empresa se suelen utilizar soluciones
de pago, principalmente por su estabilidad y soporte oficial, para la realizacin de este curso
nos vamos a apoyar en herramientas gratuitas.
En concreto:

Eclipse IDE for Java EE Developers 3.7.x de Eclipse.org: Herramienta para el


desarrollo.

Apache Tomcat 7.0.x de The Apache Software Foundation: Herramienta para la


ejecucin de aplicaciones web propuestas en este curso.

Como decimos, ambas dos son gratuitas y descargables de la red.


No obstante, vamos a comentar algunas otras herramientas de desarrollo, aunque no las
vayamos a utilizar, para el conocimiento del alumno (los servidores de aplicaciones ya se han
mencionado en la Unidad 1):

Java Enterprise Edition SDK: Es el entorno de desarrollo de referencia. Es gratuito y no


cuenta con herramientas visuales. Es decir, sera el homnimo a la JDK de Java SE.

URL: http://www.oracle.com/technetwork/java/javaee/downloads/index.html

Eclipse IDE for Java EE Developers: Es gratuito y de cdigo abierto. En concreto, es el


que utilizaremos en este curso como hemos mencionado anteriormente.

URL: http://www.eclipse.org/

Rational Application Developer: Es de pago de la empresa IBM.

23

URL: http://www.ibm.com/software/awdtools/developer/application/

NetBeans IDE: Es gratuito y de cdigo abierto.

URL: http://netbeans.org/

Oracle JDeveloper: Es de pago de la empresa Oracle.

URL: http://www.oracle.com/technetwork/developer-tools/jdev/overview/index.html

2.2

Descarga, instalacin y configuracin del entorno de desarrollo

A continuacin, describiremos los pasos para descargar, instalar y configurar las herramientas
seleccionadas

en

este

curso

anteriormente

mencionadas

para

poder

realizar

satisfactoriamente las actividades de este curso.


2.2.1 Java Runtime Environment (JRE)
Como seguramente ya conocer el alumno, el Java Runtime Environment (JRE) es el entorno
de ejecucin Java, conocido tambin con el nombre de Java Virtual Machine (o Mquina
Virtual Java).
Es imprescindible para poder ejecutar cdigo Java en un ordenador, y debido a que las dos
herramientas que vamos a utilizar: Eclipse IDE for Java EE Developers y Apache Tomcat
estn desarrollados en Java, es necesaria la existencia de un JRE en nuestra mquina para
poder ejecutarlas.
Ir a la siguiente URL http://www.oracle.com/technetwork/java/javase/downloads mediante un
navegador, y descargar el JRE 7. Para ello, seleccionar Download JRE:

24

MDULO A Unidad 2: El Entorno de Desarrollo

En la siguiente pantalla, aceptar la Licencia (Accept License Agreement) y elegir la


plataforma deseada pulsando el enlace correspondiente (por ejemplo, para Windows x64,
sera jre-7u1-windows-x64.exe).
Nota: En el momento de la redaccin de este manual, el nmero de Update del JRE 7.0 es el
1, de ah el nombre jre-7u1-windows-x64.exe; pero en el momento en el que el alumno est
siguiendo este manual, puede que ya exista un Update ms moderno y por tanto que haya
cambiado el nmero.
No obstante, a excepcin del cambio de nmero y por tanto de nomenclatura, todos los
pasos de descarga, instalacin y configuracin aqu descritos deberan seguir siendo vlidos,
por lo que el alumno puede elegir utilizar el Update 1 o uno posterior.

25

Guardar el fichero en algn directorio temporal del ordenador:

Para instalarlo, ejecutar el fichero descargado (en nuestro ejemplo, jre-7u1-windowsx64.exe), mediante doble click del ratn.

26

MDULO A Unidad 2: El Entorno de Desarrollo

Pulsar el botn Install > para comenzar la instalacin. Durante dicho proceso, aparecer
una barra mostrando el progreso de la instalacin.
Nota: La ubicacin por defecto donde se instalar el JRE es C:\Program Files\Java\jre7; si
deseamos instalarlo en una ubicacin distinta, marcar la casilla Change destination folder
antes de pulsar el botn Install >.

27

Cuando la instalacin haya terminado, y si ha sido satisfactoria, debera aparecer la siguiente


pantalla:

Pulsar el botn Close.


28

MDULO A Unidad 2: El Entorno de Desarrollo


Aunque el instalador nos diga que la instalacin ha sido satisfactoria, nunca est de ms
comprobar que efectivamente todo est bien. Para ello, una manera habitual de comprobarlo
es abrir una sesin de DOS y ejecutar el comando:
java.exe -version
Si todo est correcto, debera devolver la versin del JRE instalado:

2.2.2 Eclipse IDE for Java EE Developers


A continuacin, pasaremos a descargar e instalar Eclipse IDE, la herramienta de desarrollo
Java que vamos a utilizar durante este curso. Recordar que es importante asegurarse de la
existencia de un Java Runtime Environment (JRE) en el ordenador. Si no existiese, seguir los
pasos del apartado anterior.
Ir a la siguiente URL http://www.eclipse.org/downloads mediante un navegador, y descargar
Eclipse IDE for Java EE Developers para la plataforma deseada, pulsando sobre el enlace
correspondiente (en nuestro ejemplo, Windows 64 bits):

29

Aparecer una pgina con el mejor servidor para descargar el fichero que hemos solicitado
dependiendo de nuestra conexin y localizacin. Simplemente pulsar sobre la flecha verde y
guardar el fichero en un directorio temporal:

30

MDULO A Unidad 2: El Entorno de Desarrollo

Nota: En el momento de la redaccin de este manual, la versin de Eclipse es la 3.7.1, es


decir, el nmero de revisin es el 1, de ah el nombre eclipse-jee-indigo-SR1-win32x86_64.zip; pero en el momento en el que el alumno est siguiendo este manual, puede que
ya exista una revisin ms moderna y por tanto que haya cambiado el nmero.
31

No obstante, a excepcin del cambio de nmero y por tanto de nomenclatura, todos los
pasos de descarga, instalacin y configuracin aqu descritos deberan seguir siendo vlidos.
El alumno puede elegir por tanto el instalar el Update 1 o elegir otro Update posterior.
Descomprimir el fichero que hemos descargado (en nuestro ejemplo, eclipse-jee-indigo-SR1win32-x86_64.zip) en el disco duro donde queramos tener Eclipse. Por ejemplo:
D:\eclipse-jee-indigo-SR1-win32-x86_64
Arrancar Eclipse ejecutando:
D:\eclipse-jee-indigo-SR1-win32-x86_64\eclipse.exe

Nos preguntar por la ubicacin del workspace (o rea de trabajo) donde Eclipse va a ir
guardando todos los proyectos y ficheros que vayamos desarrollando:

Una vez hayamos seleccionado la ubicacin, pulsar el botn OK:

32

MDULO A Unidad 2: El Entorno de Desarrollo

Cerrar la pestaa de Welcome (Bienvenida):

33

2.2.3 Apache Tomcat


Por ltimo, vamos a instalar el servidor Apache Tomcat, necesario para poder ejecutar las
aplicaciones Java EE que desarrollemos en el Eclipse IDE for Java EE Developers.
Para ello, ir a la siguiente URL http://tomcat.apache.org/download-70.cgi mediante un
navegador, y descargar Tomcat para la plataforma deseada desde la seccin Core,
pulsando sobre el enlace correspondiente (en nuestro ejemplo, 64-bit Windows zip):

Descargar y descomprimir el fichero (en nuestro ejemplo, apache-tomcat-7.0.22-windowsx64.zip) en el disco duro donde queramos tener Eclipse. Por ejemplo:
D:\apache-tomcat-7.0.22

34

MDULO A Unidad 2: El Entorno de Desarrollo

Nota: En el momento de la redaccin de este manual, la versin de Tomcat es la 7.0.22, es


decir, el nmero de revisin es el 22, de ah el nombre apache-tomcat-7.0.22-windowsx64.zip; pero en el momento en el que el alumno est siguiendo este manual, puede que ya
exista una revisin ms moderna y por tanto que haya cambiado el nmero.
No obstante, a excepcin del cambio de nmero y por tanto de nomenclatura, todos los
pasos de descarga, instalacin y configuracin aqu descritos deberan seguir siendo vlidos.
Como se ha mencionado en las herramientas anteriores, es decisin del alumno, el decidir
utilizar esta revisin o una posterior.
Una vez hecho esto, ya solo queda configurar Eclipse IDE for Java EE Developers para que
utilice el Apache Tomcat que acabamos de descargar e instalar. Para ello, arrancamos de
nuevo Eclipse y seleccionamos la vista Servers:

35

Pulsaremos el botn derecho del ratn sobre la zona en blanco de esta vista, y elegiremos la
opcin New -> Server del men:

Del listado de posibles servidores, seleccionaremos Tomcat v7.0 Server y pulsaremos el


botn Next >:

36

MDULO A Unidad 2: El Entorno de Desarrollo

En la siguiente pantalla del asistente, aadiremos la ubicacin donde hemos instalado


Apache Tomcat (en nuestro ejemplo, D:\apache-tomcat-7.0.22

37

Y ya por ltimo, pulsaremos el botn Finish.


Si todo ha ido bien, ahora en la vista de Eclipse denominada Servers, debera aparecer
nuestro servidor Apache Tomcat:

Si seleccionamos con el ratn el nuevo servidor, y pulsamos el botn derecho deberamos


ver un men con las distintas acciones que podemos realizar con l:

38

MDULO A Unidad 2: El Entorno de Desarrollo

Seleccionaremos la opcin Start y veremos como aparecer una nueva vista denominada
Console donde ir apareciendo el log del servidor. En este caso, deberamos ver cmo va
saliendo toda la informacin del arranque. Algo parecido a esto:

Volviendo a la vista Servers, veremos como el estado del servidor ahora ha cambiado
poniendo [Started, Synchronized].
Podemos parar el servidor nuevamente desde el mismo men de opciones desde donde lo
arrancamos en el paso anterior y una vez lo haya hecho, cerrar Eclipse.
Con esto damos por finalizada la instalacin y configuracin del entorno de desarrollo
necesario para llevar a cabo este curso.

39

PARA RECORDAR

En esta unidad hemos aprendido a instalar la herramienta de desarrollo, Eclipse


IDE for Java EE Developers, el servidor de aplicaciones Apache Tomcat y la Java
Runtime Environment (JRE) necesarias para la implementacin de las aplicaciones
web propuestas en este curso.

40

Unidad de Aprendizaje 3

PROTOCOLO HTTP Y
LENGUAJE HTML

NDICE
3.1

Introduccin ................................................................... 43

3.2

El protocolo HTTP ......................................................... 44


3.2.1 Direccin de Internet o URL..........................................45
3.2.2 Conversaciones HTTP ...................................................46
3.2.3 Sniffer HTTP ....................................................................51

3.3

El lenguaje HTML........................................................... 54
3.3.1 La etiqueta HTML ...........................................................55
3.3.2 La pgina HTML..............................................................56
3.3.3 El formulario HTML.........................................................57
3.3.3.1 Camposdetexto ......................................................58
3.3.3.2 reasdetexto ..........................................................59
3.3.3.3 Checkboxes...............................................................60
3.3.3.4 Radiobuttons............................................................61
3.3.3.5 ListasyCombos ........................................................62
3.3.3.6 Botones ....................................................................63
3.3.3.7 Camposocultos ........................................................64

3.4

Ensamblado y despliegue ............................................ 64

PARA RECORDAR.................................................................... 67

MDULO A Unidad 3: El protocolo HTTP y el lenguaje HTML

3.1

Introduccin

Al estudiar las aplicaciones Java EE (o Web), es imposible no hablar primero de la red de


redes: Internet, y de los fundamentos sobre los que se apoya. Simplificando mucho, esos dos
fundamentos son el protocolo de comunicaciones HTTP (HiperText Transfer Protocol) y el
lenguaje de etiquetado HTML (HiperText Markup Language).
Vamos a hablar un poco ms en detalle de lo que es un sistema de comunicaciones en
general, y el sistema de comunicaciones en el que se basa Internet: TCP/IP.
Un sistema de comunicaciones en general, se representa como una pila de capas en las que
cada una aporta una funcionalidad concreta a la comunicacin. Existe el modelo de referencia
OSI, que representa los sistemas de comunicacin desde un punto de vista terico en 7
capas y luego sistemas de comunicacin concretos reales, que implementan ese modelo de
referencia de distintas formas, como por ejemplo el TCP/IP o el SNA.
En el siguiente diagrama se puede ver la comparativa entre el modelo de referencia OSI y el
TCP/IP que es el sistema de comunicaciones que utiliza Internet:

Muy brevemente, repasamos lo que cubre cada uno de los niveles:


1. Fsico: Define las caractersticas fsicas de la red material.
2. Enlace: Proporciona el servicio de envo de datos a travs del enlace fsico.
3. Red: Gestiona las conexiones de red para las capas superiores.
4. Transporte: Proporciona servicios de deteccin y correccin de errores.
5. Sesin: Gestiona las conexiones entre aplicaciones cooperativas.
6. Presentacin: Estandariza la forma en la que se presentan los datos a las aplicaciones.
7. Aplicacin: Aplicaciones que usan la red.
43

Cono podemos observar, el TCP/IP implementa los niveles tericos en cuatro, a travs de
distintos protocolos como IP en el nivel que llama Internet, TCP y UDP entre otros en el nivel
que llama Transporte, y HTTP, FTP, Telnet, etc en el nivel que llama Aplicacin. Es en este
ltimo nivel donde se encuentra el protocolo HTTP que realmente nos interesa para programar
aplicaciones Java EE aunque este, sin el resto de los niveles sera intil. De ah que se hayan
mencionado en esta introduccin.
Por otro lado, tenamos el lenguaje de etiquetado HTML, la otra piedra angular sobre la que se
sustenta Internet. El HTML es el lenguaje mediante el cual definimos los contenidos que fluyen
por Internet, conocidas como pginas HTML o pginas Web.
Y quizs sin saberlo, todos los das estamos usando ambos dos fundamentos. Los
navegadores web (IExplorer, Firefox, Chrome, Opera) no son mas que aplicaciones que
implementan el protocolo HTTP a travs del cual se reciben bajo peticin pginas HTML.
Por qu es tan importante tener claro los conceptos del HTTP y HTML entonces? Porque las
aplicaciones Java EE que vamos a aprender a desarrollar, son las que estn al otro lado
sirviendo las peticiones de los navegadores web. Por tanto, van a tener que entender el
protocolo HTTP y van a tener que saber contestar con pginas HTML que muestran la
informacin solicitada.
Nota: como decamos al inicio de esta introduccin, esta es una visin muy simplista pero que
proporciona una idea clara. Es simplista en el sentido de que no solo se utiliza el protocolo
HTTP (aunque si en la mayora de los casos) ni siempre se utiliza HTML como medio para
mostrar la informacin (aunque nuevamente si en la mayora de los casos). Otras opciones a
modo de ejemplo, mucho menos utilizadas, seran protocolos como FTP o Telnet, y lenguajes
de etiquetado como WML o cHTML.

3.2

El protocolo HTTP

Como hemos dicho ya, el protocolo HTTP es el protocolo fundamental desde el punto de vista
del desarrollo de aplicaciones Java EE. Es el encargado de la transferencia de los recursos
que componen la red.
Es un protocolo que sigue un esquema de peticin respuesta (request response) entre un
cliente (habitualmente un navegador) y un servidor (habitualmente un servidor de aplicaciones
Java EE como ya vimos en las unidades anteriores) donde el cliente solicita un recurso y el
servidor se lo devuelve.
Actualmente se encuentra en su versin 1.1, y es un estndar definido por el IETF (RFC 2616):
http://www.ietf.org/rfc/rfc2616.txt

44

MDULO A Unidad 3: El protocolo HTTP y el lenguaje HTML


3.2.1 Direccin de Internet o URL
Las URLs (Uniform Resource Locator) identifican de forma unvoca un recurso en la red. Un
recurso que puede ser una pgina HTML, una imagen JPG o incluso un componente Java EE
como un Java Servlet o una JavaServer Page (JSP).
Las URLs constan de las siguientes partes:
Protocolo: HTTP, HTTPS, FTP, Telnet a utilizar para acceder al recurso.
Servidor: Direccin IP o nombre del servidor donde reside el servicio o aplicacin que
sabe servir el recurso.
Puerto: Donde est escuchando el servicio o aplicacin que sabe servir el recurso.
Path (o camino): Donde est ubicado el recurso.
Recurso: El recurso como tal que estamos solicitando.
Utilizando el siguiente formato:
Protocolo://Servidor:Puerto/Path/Recurso
Nota: Es importante mantener el formato de los dos puntos y las barras.
Lo entenderemos mucho mejor con un ejemplo muy sencillo que la mayora hemos usado
alguna vez al buscar algo en Google. Para ello, lo que hacemos es escribir en el navegador la
siguiente direccin de Internet o URL:
http://www.google.es:80/index.html
Qu significa realmente esto que escribimos habitualmente para buscar cosas en Internet?
Significa que mediante el protocolo HTTP, nos conectamos a la aplicacin que est
escuchando en el puerto 80 del servidor www.google.es y le solicitamos el recurso
index.html que est en el directorio raz (porque no hemos especificado ningn path).
Muchos estaris pensando que vosotros no escribs nunca ese 80, o que nunca habais
especificado eso de index.html; correcto. Qu ocurre entonces? Lo que ocurre, es que para
ahorrar trabajo a los usuarios, se establecen muchas cosas por defecto.
Por ejemplo, se ha establecido un puerto por defecto para cada protocolo de manera que si
no decimos el puerto a utilizar, en este caso el navegador aade sin que nosotros lo
sepamos el puerto correspondiente. Algunos puertos por defecto son:
HTTP: 80
HTTPS: 443
FTP: 21
Telnet: 23
etc
45

Y con el nombre del recurso ocurre igual. Est establecido que por defecto si no se
especifica el nombre del recurso, las aplicaciones prueben con unos nombres por defecto
que suelen ser:
index.html
index.htm
index.jsp
etc
Por tanto, una URL equivalente a la analizada y con mismo resultado sera:
http://www.google.es
Los servidores en Internet se identifican mediante direcciones IP que consisten en cuatro
grupos de nmeros desde el 0 al 255 separados por puntos, por ejemplo:
74.125.39.103
Todo servidor en Internet tiene asignada una direccin IP nica. Si no fuese as, sera
inaccesible porque al hacer una peticin, el sistema de comunicaciones TCP/IP no sabra
con cul conectar. Como el uso de estas direcciones es algo complejo para los usuarios
(difciles de recordar, fcil de cometer un error), existen unos servidores especiales
denominados DNS (Domain Name Server o Servidores de Nombres de Dominio) que se
encargan de traducir nombres legibles y fciles de recordar por los usuarios a direcciones IP.
Esta traduccin mediante la conexin a los servidores DNS la hace el sistema de
comunicaciones TCP/IP, que comentamos en la introduccin, automticamente sin la
intervencin del usuario.
Por ejemplo, en el momento de la redaccin de este manual, la direccin IP de
www.google.es era la del ejemplo: 74.125.39.103, es decir, que en el navegador deberamos
ver la misma pgina si escribiramos:
http://74.125.39.103
o si escribiramos:
http://ww.google.es
3.2.2 Conversaciones HTTP
Como ya comentamos al inicio de este captulo, HTTP es un protocolo que sigue un
esquema de peticin respuesta (request response) entre un cliente (habitualmente un
navegador) y un donde el cliente solicita un recurso y el servidor se lo devuelve.
Una peticin HTTP se compone a grandes rasgos de:
Mtodo HTTP: se trata de la accin a realizar. Algunos ejemplos como veremos mas
adelante son GET y POST.
Recurso sobre el que actuar: es decir, una URL.
46

MDULO A Unidad 3: El protocolo HTTP y el lenguaje HTML


Parmetros: como los argumentos de un mtodo Java.
Por el otro lado, una respuesta HTTP se compone de:
Cdigo de estado: un cdigo numrico que indica qu ocurri con la peticin.
Tipo del contenido: que indica el formato de la respuesta. Por ejemplo, una pgina
HTML, un documento XML, una imagen JPG, etc
Contenido: la respuesta como tal.
El envo de peticiones y respuestas, se realiza mediante un mensaje HTTP, es decir, una
estructura bien definida que sigue una serie de reglas que todo cliente y servidor que
mantengan una conversacin HTTP deben conocer y cumplir.
Un mensaje HTTP se compone de:
Una cabecera: que incluye informacin tcnica.
Un cuerpo: que incluye el contenido del mensaje como tal.
Los mtodos HTTP que se pueden utilizar como parte de una peticin HTTP son los
siguientes:
HEAD: solicita un recurso al servidor, pero que la respuesta no ha de incluir el
contenido, solo las cabeceras.
GET: solicita un recurso al servidor (normalmente esttico como por ejemplo un
fichero).
POST: solicita un recurso al servidor (normalmente dinmico, es decir, la ejecucin de
una aplicacin).
PUT: solicita el envo de un recurso al servidor.
DELETE: solicita la eliminacin de un recurso en el servidor.
TRACE: solicita al servidor que le conteste lo mismo que le solicita. Se utiliza
normalmente para analizar problemas en la comunicacin donde entre el cliente y el
servidor existen otra serie de elementos de comunicaciones como proxies, firewalls,
etc
OPTIONS: solicita al servidor conocer qu mtodos HTTP soporta.
CONNECT: solicita al servidor cambiar a un sistema de comunicacin cifrada (HTTPS).
Mas adelante, veremos un poco ms en detalle los mtodos GET y POST que son los
utilizados habitualmente en la programacin de aplicaciones Java EE incluyendo algn
ejemplo.
Los cdigos de estado que se pueden recibir en una respuesta HTTP son muchos y
variados. Aqu comentamos algunos:
Cdigos 2xx: Peticin realizada con xito.
47

o 200: OK. Este es el cdigo que deberamos recibir habitualmente.


o 204: Sin contenido.
o 205: Sin contenido, recargar.
o 206: Contenido parcial.
Cdigos 3xx: Redireccin.
o 301: Recurso movido de forma permanente.
o 303: Ver otro recurso.
o 307: Recurso movido de forma temporal.
Cdigos 4xx: Error del cliente.
o 400: Peticin incorrecta. Se produce si el mensaje HTTP de peticin tiene
errores. No es habitual cuando se usa un navegador, pero si, s estamos
programando un cliente HTTP.
o 403: Prohibido. Se produce cuando intentamos acceder a un recurso
protegido y no tenemos acceso.
o 404: No encontrado. Se produce cuando se solicita un recurso no existente en
el servidor.
Cdigos 5xx: Error en el servidor.
o 500: Error interno. Ms habitual de lo que desearamos.
o 503: Servicio no disponible.
o 505: Versin HTTP no soportada.
Vamos a centrarnos en los dos mtodos, es decir, en los dos tipos de peticin HTTP ms
comunes en el desarrollo de aplicaciones Java EE y que con total seguridad utilizaremos:
GET y POST.
GET es el ms simple, y se suele utilizar para solicitar un recurso esttico, es decir, un
fichero de tipo HTML, JPG, XML. No obstante, tambin puede ser usado para solicitar un
recurso dinmico, es decir, por ejemplo un componente de una aplicacin web, y por tanto,
permite el envo de parmetros. Eso si, dichos parmetros van aadidos como parte de la
URL y son visibles, lo que desde un punto de vista de seguridad puede ser un problema.
Veamos un ejemplo de una peticin HTTP con el mtodo GET de un servlet Java que suma
dos nmeros:
GET /EjemploWeb/Sumador?param1=12&param2=41 HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, */*
Referer: http://127.0.0.1/Practica23a/index.html
Accept-Language: en-us,es;q=0.5
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;
SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)
Host: 127.0.0.1:8080
48

MDULO A Unidad 3: El protocolo HTTP y el lenguaje HTML


Connection: Keep-Alive
Este mensaje HTTP, que en concreto es una peticin (lo sabemos porque su primera lnea es
un mtodo HTTP en vez de un cdigo de estado) solo tiene cabecera. No tiene cuerpo.
La primera lnea de toda peticin HTTP siempre es el mtodo HTTP, seguido del recurso
sobre el que queremos ejecutar la accin, y por ltimo la versin de protocolo HTTP utilizada
por el cliente.
Despus, hay una secuencia de distintas propiedades (de la forma nombre: valor) que
aaden informacin tcnica al mensaje. Por ejemplo, qu tipo de cliente se est utilizando
(User-Agent). Hay muchas, y solo comentaremos a lo largo del curso aquellas que tengan
relevancia.
En este ejemplo, estamos pidiendo el recurso /EjemploWeb/Sumador pasndole dos
parmetros: param1 y param2 con los valores 12 y 41. Como se puede ver, se indica que
hay parmetros mediante el smbolo ? y se separan los parmetros (parejas de
nombre=valor) mediante el smbolo &.
Veamos ahora la respuesta HTTP de este mismo ejemplo:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=304CE17CCEB55869A606CE06271F915B;
Path=/EjemploWeb
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 314
Date: Sun, 08 Jun 2008 09:19:19 GMT
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html;
charset=ISO-8859-1">
<TITLE>Calculadora</TITLE>
</HEAD>
<BODY>
El resultado de la suma de 12 y 41 es: 53
</BODY>
</HTML>
En este caso, el mensaje HTTP si que incluye tanto cabecera como cuerpo.
Lo primero, sabemos que es una respuesta porque la primera lnea comienza con la versin
HTTP utilizada por el servidor, seguido del cdigo de estado. En este caso, un 200 que
indica que todo ha ido bien.
Hay otras cabeceras adicionales muy importantes para saber interpretar la respuesta como
son: Content-Type, que indica el tipo de contenido del cuerpo (en este caso un fichero
HTML) y Content-Lenght, que indica el tamao del contenido (en este caso 314 bytes).
Separado por un salto de lnea viene el cuerpo del mensaje HTTP que como ya nos indicaba
la cabecera es un fichero HTML (ms adelante, en esta misma unidad, hablaremos del
lenguaje HTML).
49

POST es el mtodo que habitualmente se utiliza para enviar parmetros, porque van en el
cuerpo de la peticin en vez de aadidos a la URL del recurso solicitado.
Veamos el mismo ejemplo que antes para identificar las diferencias. En este caso la peticin
sera:
POST /EjemploWeb/Sumador HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, */*
Referer: http://127.0.0.1/EjemploWeb/index.html
Accept-Language: en-us,es;q=0.5
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;
SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)
Host: 127.0.0.1:8080
Content-Length: 19
Connection: Keep-Alive
Cache-Control: no-cache
param1=45&param2=21
Nuevamente identificamos que se trata de una peticin HTTP porque la primera lnea
comienza con un mtodo HTTP. Y vemos, que a diferencia de lo que ocurra con el mtodo
GET, en esta ocasin la URL no incluye ningn parmetro sino que el mensaje tiene un
cuerpo con dichos parmetros.
Hay alguna diferencia en alguna cabecera ms, pero tampoco entraremos en tanto detalle.
La respuesta sera:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=304CE17CCEB55869A606CE06271F915B;
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 314
Date: Sun, 08 Jun 2008 09:27:24 GMT
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html;
charset=ISO-8859-1">
<TITLE>Calculadora</TITLE>
</HEAD>
<BODY>
El resultado de la suma de 45 y 21 es: 66
</BODY>
</HTML>
Como vemos, es igual que la del ejemplo anterior, ya que lo que nos devuelve el servidor si
le pedimos lo mismo (aunque sea por dos mtodos distintos) siempre ser lo mismo.
Los parmetros que se envan en una peticin, pueden ser cualquier carcter alfanumrico
ASCII, incluyendo los caracteres: . (punto), - (guion), * (asterisco) y _ (subrayado). Cualquier
otro tipo de carcter ha de ir codificado:
El espacio en blanco con el carcter + (suma).
Cualquier otro carcter con un valor hexadecimal de la forma %xx. Por ejemplo, la
(ee), con %F1. En Internet estn las tablas de conversin y el propio lenguaje Java
50

MDULO A Unidad 3: El protocolo HTTP y el lenguaje HTML


tiene mtodos para decodificar y decodificar caracteres de una URL en la clase
java.net.Encoder y java.net.Decoder
Es importante tener presente, que si se usa el mtodo GET para el envo de dichos
parmetros, es responsabilidad del desarrollador la codificacin. Por el contrario, si se usa el
mtodo POST, la codificacin se realiza de forma automtica.
No obstante, en los casos en los que el cliente HTTP sea un navegador, como ocurrir la
mayora de las veces en este curso, es el propio navegador el que se encarga de dicha
codificacin automticamente.

3.2.3 Sniffer HTTP


En principio, toda esta comunicacin HTTP suele ocurrir sin un conocimiento muy profundo
por parte del desarrollador de aplicaciones Java EE. Pero como iremos viendo en las
sucesivas unidades, si que hay conceptos de los tratados hasta este momento en esta
unidad que son imprescindibles de conocer.
E incluso, en muchas ocasiones, para depurar un problema de nuestras aplicaciones, ser
imprescindible analizar los mensajes HTTP que fluyen entre el cliente (por ejemplo, un
navegador) y nuestra aplicacin Java EE servidora.
Ahora, y cmo podemos ver los mensajes HTTP que viajan por la red entre el cliente y el
servidor? Para esto existen unas herramientas habituales en el mundo de las redes de
comunicaciones que se llaman sniffers, que se encargan de monitorizar el trfico de red. El
funcionamiento habitual, consiste en ponerse entre medias del cliente y del servidor, y
registrar todo el trfico que fluye: tanto peticiones como respuestas.
La herramienta de desarrollo que utilizamos en este curso, Eclipse IDE for Java EE
Developers, incluye un sniffer denominado TCP/IP Monitor.
Para acceder a l, ir a las opciones de men Window -> Show view -> Other:

51

Seleccionar la vista de TCP/IP Monitor de la carpeta Debug:

52

MDULO A Unidad 3: El protocolo HTTP y el lenguaje HTML


Se abrir el TCP/IP Monitor en una pestaa ms:

En sus propiedades, aadimos una configuracin mediante el botn Add, estableciendo


el puerto por el que escucha, y a qu direccin y puerto debe renviar todo el trfico. En
nuestro caso, si monitorizamos el trfico con el Servidor de Aplicaciones Tomcat que
tenemos en el propio Eclipse IDE, podramos decirle que escuche en el puerto 80 (por
ejemplo) y que renve a nuestra misma mquina al puerto 8080 (puerto por donde escucha
por defecto el Servidor de Aplicaciones Tomcat):

Por ltimo, lo arrancamos mediante el botn Start.


Ahora solo queda, realizar peticiones desde nuestro navegador al servidor, pero en vez de
hacerlo directamente al puerto 8080, lo haremos a travs del puerto 80 para que el sniffer
intercepte las comunicaciones y las renve. As, escucharemos en el puerto 80 de nuestra
53

mquina y lo renviaremos al 8080 del servidor de aplicaciones (que en este ejemplo, tambin
est en nuestra mquina):

De momento, no hay que preocuparse mucho por su funcionamiento. Ya tendremos ocasin


de probarlo con las primeras aplicaciones Java EE que desarrollemos

en la siguiente

unidad.

3.3

El lenguaje HTML

El HTML (HiperText Markup Languaje) es el lenguaje utilizado para crear documentos web (o lo
que comnmente se denominan pginas web). Bsicamente se trata de un lenguaje de
etiquetado, que define la estructura y el contenido de un documento a ser compartido y
accedido en Internet a travs de un navegador web.
Junto con el protocolo HTTP son la base sobre la que se construy la red de redes conocida
como Internet.
Este lenguaje est estandarizado bajo la supervisin del W3C. En el momento de la redaccin
de este manual, la ltima versin del lenguaje HTML es la 4.01:
http://www.w3.org/TR/html4/
aunque la siguiente versin, 5.0, est en proceso de definicin:
http://www.w3.org/TR/html5/
No obstante, el lenguaje HTML requerira un manual dedicado para cubrir todas sus
caractersticas y posibilidades. En nuestro caso, al igual que hemos hecho con el protocolo
HTTP, solo haremos un breve recorrido introductorio para conocer lo imprescindible que nos
permita desarrollar aplicaciones Java EE.
54

MDULO A Unidad 3: El protocolo HTTP y el lenguaje HTML


Para profundizar en el lenguaje HTML recomendamos el curso de Aula Mentor HTML.
Adicionalmente, junto con el lenguaje HTML, han ido surgiendo otras tecnologas y lenguajes
para dotar a las pginas web de cierto dinamismo y potencia. Algunas de ellas son el lenguaje
JavaScript, tecnologas AJAX, etc que no cubriremos en este curso.
Nuevamente, en la oferta de cursos de Aula Mentor, los hay orientados a estas tecnologas.

3.3.1 La etiqueta HTML


Como ya hemos dicho, el lenguaje HTML est orientado a etiquetas. Una etiqueta no es ms
que un elemento que define qu se debe hacer o cmo se debe presentar la informacin
que viene a continuacin de ella dentro de una pgina web.
Normalmente, las etiquetas se utilizan a pares, es decir, etiqueta de inicio de definicin y
etiqueta de final de definicin.
El formato es el siguiente:
<nombre_etiqueta [atributo1="valor1", atributo2="valor2",...]>
[contenido]
[</nombre_etiqueta> ]
Como podemos observar, las etiquetas van definidas entre los caracteres < y >. Y para
diferenciar cundo se trata de una etiqueta de apertura o de cierre, en la de cierre se utiliza
el carcter / despus del carcter <.
Entre la pareja de etiquetas, se aade el contenido que se ver afectado por el significado
de dichas etiquetas.
Adicionalmente, las etiquetas pueden permitir atributos que complementan el significado y
comportamiento de la etiqueta.
Vemoslo con un ejemplo rpido:
<FONTsize="3"color="red">
Holamundo
</FONT>
Este ejemplo es un fragmento de una pgina o documento HTML. Y en l, podemos
observar fcilmente, que se trata del uso de la etiqueta FONT. En la primera lnea vemos el
uso de la etiqueta de inicio <FONT>, y en la tercera lnea la etiqueta de final </FONT>.
El contenido que se va a ver afectado por el significado y comportamiento de la etiqueta es
el texto Hola mundo de la segunda lnea.
Adicionalmente, podemos observar que la etiqueta de inicio incluye una serie de atributos,
como son size (tamao) y color. Una etiqueta de final, nunca lleva atributos.
El resultado visual en un navegador web de una pgina web, que incluyera este fragmento
sera este:

55

3.3.2 La pgina HTML


Una vez visto la base del lenguaje HTML (las etiquetas), vamos a centrarnos en la pgina o
documento HTML (tambin nombrada pgina web).
Una pgina o documento HTML, es un fichero de texto con extensin *.htm o *.html que
contiene una informacin formateada mediante el lenguaje HTML.
Aunque los navegadores web, desde siempre han sido muy permisivos con las pginas
HTML mal formateadas (etiquetas de final no aadidas, estructura de la pgina errnea,
etc) vamos a intentar crearlas siempre correctamente.
La estructura mnima de una pgina HTML sintcticamente correcta, es la siguiente:
<!DOCTYPEHTMLPUBLIC"//W3C//DTDHTML4.01Transitional//EN">
<HTML>
<HEAD>
<TITLE>MiprimerHTML</TITLE>
</HEAD>
<BODY>

Miprimerejercicio
</BODY>
</HTML>
Este cdigo HTML debera ir salvado en un fichero de extensin *.html y al abrirlo en un
navegador, veramos algo as:

La primera lnea es un tanto especial. Se trata de una etiqueta de descripcin tcnica del
fichero HTML donde especifica la versin de HTML utilizada, entre otras cosas.

56

MDULO A Unidad 3: El protocolo HTTP y el lenguaje HTML


Pero lo realmente importante viene despus, y es, la estructura de una pgina HTML. Toda
pgina HTML debe ir siempre definida por la etiqueta HTML.
Una pgina HTML se divide en dos secciones distintas:
La cabecera, definida por la etiqueta HEAD.
El cuerpo, definido por la etiqueta BODY.
En la cabecera de una pgina HTML se aadir informacin relacionada con la pgina, como
por ejemplo su ttulo (definido por la etiqueta TITLE), mientras que en el cuerpo, ir el
contenido de la pgina como tal. En nuestro caso, simplemente va el texto Mi primer
ejercicio.
Como se puede observar en la imagen de ejemplo, los navegadores web normalmente
muestran el ttulo de la pgina HTML en la pestaa que est mostrando dicha pgina (u
otros, en la barra de ttulo del navegador).
Otro contenido tpico de la cabecera de una pgina HTML, es informacin especfica para
algunos buscadores de Internet, que les ayuda a indexar y categorizar la pgina.

3.3.3 El formulario HTML


Como ya hemos comentado, este curso no tiene como objetivo el lenguaje HTML sino la
programacin de aplicaciones Java EE. Por ello, no vamos a enumerar y explicar las
decenas de etiquetas existentes en el lenguaje HTML,
Solo nos vamos a centrarnos en un subconjunto que si son imprescindibles para interactuar
con aplicaciones Java EE servidoras que son las relacionadas con los formularios HTML.
Un formulario es la presentacin visual de entrada de datos en una pgina HTML para ser
enviados a una aplicacin servidora.
La etiqueta que lo define es FORM. Dicha etiqueta puede contener distintos atributos,
algunos obligatorios y otros opcionales.
Los dos atributos obligatorios son:
Method: El mtodo HTTP que se va a utilizar al enviar al servidor la informacin
recogida en el formulario.
Action: El recurso o componente del servidor al que se le va a enviar la informacin.
Otros atributos posibles son: name, target, id, etc
Ejemplo:
<FORMmethod=POSTaction=/EjemploWeb/EjemploServlet>
</FORM>

57

Este formulario va a enviar a un Java Servlet del servidor mediante el mtodo HTTP POST
toda la informacin que contenga. De momento, tal cual est en el ejemplo, no contiene
ninguna informacin.
Un formulario puede contener distintos elementos para recoger informacin del usuario:
Campos de texto.
reas de texto.
Checkboxes.
Radiobuttons.
Listas y combos.
Botones.
Campos ocultos.
Veamos uno por uno.
3.3.3.1 Camposdetexto
Un campo de texto se define mediante la etiqueta INPUT y su atributo type con el valor
text.
Admite otros atributos como son:
Name: el nombre del campo y por tanto, nombre del parmetro que viajar al servidor.
Value: valor que debe aparecer por defecto si as se desea.
Size: tamao del campo en la pantalla desde un punto de vista visual.
Maxlength: nmero mximo de caracteres que se pueden introducir en este campo.
Disabled: no tiene un valor, sino que su sola presencia significa que el campo est
deshabilitado.
Esta etiqueta no requiere su homnima de final.
Ejemplo:
<FORMmethod=POSTaction=/EjemploWeb/EjemploServlet>
Introduzcasunombre:

<INPUTtype=textname=nombremaxlength=20>
</FORM>
El navegador mostrara algo as:

58

MDULO A Unidad 3: El protocolo HTTP y el lenguaje HTML

Existe un caso particular de campo de texto, que es el utilizado para introducir informacin
secreta (como por ejemplo una contrasea) donde no se quiere que se pueda leer la
informacin tecleada.
Se define igual que el campo de texto con la diferencia de que el atributo type debe tener
el valor password.
Ejemplo:
<FORMmethod=POSTaction=/EjemploWeb/EjemploServlet>
Introduzcasucontrasea:
<INPUTtype=passwordname=contrasenamaxlength=20>
</FORM>
El navegador mostrara algo as:

3.3.3.2

reasdetexto

Un rea de texto se define mediante la etiqueta TEXTAREA.


Admite los siguientes atributos:
Name: el nombre del campo y por tanto, nombre del parmetro que viajar al servidor.
Cols: el nmero de columnas visible.
Rows: el nmero de filas visible.
Readonly: no tiene un valor, sino que su sola presencia significa que el campo es de
solo lectura.
Disabled: no tiene un valor, sino que su sola presencia significa que el campo est
deshabilitado.
59

Esta etiqueta si requiere su homnima de final. Y el contenido que queramos que aparezca
por defecto en ella si as lo deseamos, debe ir entre ambas etiquetas.
Ejemplo:
<FORMmethod=POSTaction=/EjemploWeb/EjemploServlet>
Introduzcasuscomentarios:<BR>
<TEXTAREAname=comentarioscols=10rows=20>
</TEXTAREA>
</FORM>
El navegador mostrara algo as:

3.3.3.3

Checkboxes

Una checkbox se define mediante la etiqueta INPUT y su atributo type con el valor
checkbox.
Admite otros atributos como son:
Name: el nombre del campo y por tanto, nombre del parmetro que viajar al servidor.
Value: el valor del campo en caso de estar seleccionado.
Checked: no tiene un valor, sino que su sola presencia significa que la checkbox est
seleccionada por defecto.
Disabled: no tiene un valor, sino que su sola presencia significa que el campo est
deshabilitado.
Esta etiqueta no requiere su homnima de final.
Ejemplo:
<FORMmethod=POSTaction=/EjemploWeb/EjemploServlet>
Seleccionesusdeportesfavoritos:
<BR>
Ftbol:<INPUTtype="checkbox"name="futbol"value="true"
checked><BR>
60

MDULO A Unidad 3: El protocolo HTTP y el lenguaje HTML


Baloncesto:<INPUTtype="checkbox"name="baloncesto"
value="true"><BR>
Petanca:<INPUTtype="checkbox"name="petanca"value="true">
</FORM>
El navegador mostrara algo as:

3.3.3.4

Radiobuttons

Un radiobutton se define mediante la etiqueta INPUT y su atributo type con el valor radio.
Admite otros atributos como son:
Name: el nombre del campo y por tanto, nombre del parmetro que viajar al servidor.
Si varios radiobuttons comparten el mismo nombre, entonces forman un grupo donde
solo uno de ellos puede estar seleccionado.
Value: el valor del campo en caso de estar seleccionado.
Checked: no tiene un valor, sino que su sola presencia significa que el radiobutton est
seleccionada por defecto.
Disabled: no tiene un valor, sino que su sola presencia significa que el campo est
deshabilitado.
Esta etiqueta no requiere su homnima de final.
Ejemplo:
<FORMmethod=POSTaction=/EjemploWeb/EjemploServlet>
Seleccionesusexo:<BR>
<INPUTtype="radio"name="sexo"value="tipo1"checked>Hombre
<BR>
<INPUTtype="radio"name="sexo"value="tipo2">Mujer<BR>
</FORM>
El navegador mostrara algo as:

61

3.3.3.5

ListasyCombos

Tanto las listas como los combos se definen mediante la etiqueta SELECT.
Admite los siguientes atributos:
Name: el nombre del campo y por tanto, nombre del parmetro que viajar al servidor.
Size: especifica el nmero de valores visible. Si solo es visible un valor, se mostrar
como un Combo. Si son visibles dos o ms, se mostrar como una lista.
Multiple: no tiene un valor, sino que su sola presencia significa que se pueden
seleccionar ms de un elemento a la vez.
Disabled: no tiene un valor, sino que su sola presencia significa que el campo est
deshabilitado.
Esta etiqueta si requiere su homnima de final. Y las distintas opciones que vayan a formar
parte de la lista debern ir definidas entre ambas mediante la etiqueta OPTION.
La etiqueta OPTION admite los siguientes atributos:
Value: el valor del campo en caso de estar seleccionado.
Selected: no tiene un valor, sino que su sola presencia significa que esta opcin est
seleccionada por defecto.
Esta etiqueta si requiere su homnima de final. Y el contenido que queramos que aparezca
como opcin debe ir entre ambas etiquetas.
Ejemplo:
<FORMmethod=POSTaction=/EjemploWeb/EjemploServlet>
Seleccioneelpostre:<BR>
<SELECTname="postre"size="3">

<OPTIONvalue="op1">Fruta</OPTION>

<OPTIONvalue="op2"selected>Helado</OPTION>

<OPTIONvalue="op3">Cuajada</OPTION>

<OPTIONvalue="op4">Tarta</OPTION>
</SELECT>
</FORM>
62

MDULO A Unidad 3: El protocolo HTTP y el lenguaje HTML


El navegador mostrara algo as:

3.3.3.6

Botones

Un botn se define mediante la etiqueta INPUT. Y dependiendo del valor que tenga su
atributo type ser de un tipo u otro:
Button: se trata de un botn genrico que por s solo no hace nada. Hay que
acompaarlo de JavaScript, por ejemplo, para que realice alguna operativa.
Submit: se trata de un botn que al ser pulsado enva toda la informacin recogida en
el formulario al recurso del servidor identificado en el atributo action del formulario
mediante el mtodo HTTP especificado en el atributo method del formulario.
Reset: se trata de un botn que al ser pulsado borra toda la informacin recogida en el
formulario.
Admite otros atributos como son:
Name: el nombre del botn, que puede ser til cuando se programa con JavaScript en
la pgina HTML.
Value: el texto que aparece escrito en el botn.
Disabled: no tiene un valor, sino que su sola presencia significa que el botn est
deshabilitado.
Esta etiqueta no requiere su homnima de final.
Ejemplo:
<FORMmethod=POSTaction=/EjemploWeb/EjemploServlet>
<INPUTtype="submit"value="Enviar">
<INPUTtype="reset"value="Borrar">
</FORM>
El navegador mostrara algo as:

63

3.3.3.7

Camposocultos

Existen ocasiones, en las que nos interesar que como parte del formulario se enve
informacin no visible para el usuario pero necesaria para la lgica de nuestra aplicacin.
Dichos campos se definen mediante la etiqueta INPUT y su atributo type con el valor
hidden.
Admite otros atributos como son:
Name: el nombre del campo y por tanto, nombre del parmetro que viajar al servidor.
Value: el valor del campo, no modificable por el usuario.
Esta etiqueta no requiere su homnima de final.
Ejemplo:
<FORMmethod=POSTaction=/EjemploWeb/EjemploServlet>
<INPUTtype=hiddenname=usuariovalue=1234>
</FORM>
Evidentemente, en el navegador no se vera nada.
Pues bien, esto es todo lo que hay que conocer de HTML para poder interactuar entre el
usuario y la aplicacin Java EE mediante un navegador web. Cualquier otra etiqueta HTML
ya sera para dar formato a la pgina: tablas, cabeceras, imgenes, enlaces, frames, etc

3.4

Ensamblado y despliegue

Las pginas HTML pueden desplegarse de distintas maneras.


Por ejemplo, se pueden desplegar en un Servidor Web como Apache HTTP Server
(http://httpd.apache.org/) o Internet Information Server (http://www.iis.net/) entre otros. Estos
servidores, se limitan a servir webs estticas basadas en pginas HTML y sus recursos:
imgenes, hojas de estilo, etc...
Pero como vimos en la primera unidad de este curso, tambin se pueden desplegar como
parte de una aplicacin Java EE (dentro de un mdulo web) en un Servidor de Aplicaciones
Java EE.
64

MDULO A Unidad 3: El protocolo HTTP y el lenguaje HTML


Esta segunda opcin ser la que estudiaremos y utilizaremos a lo largo del curso, pero a partir
de la siguiente unidad.
De momento, en las actividades de esta unidad, nos limitaremos a crear las pginas HTML en
el sistema de archivos local y abrirlas con el navegador accediendo al disco duro (no
escribiendo ninguna URL de un servidor).
Por ejemplo, con Mozilla Firefox 10:

O con Internet Explorer 9:

65

66

PARA RECORDAR

El modelo de referencia OSI representa los sistemas de comunicacin desde un


punto de vista terico en 7 capas implementado en un sistema de comunicacin
real como es el TCP/IP.

El protocolo HTTP es el encargado de la transferencia de los recursos, de las


aplicaciones web, que componen la red. Estos recursos son identificados de forma
unvoca mediante las URLs, que tienen el siguiente formato:
Protocolo://Servidor:Puerto/Path/Recurso

Las conversaciones HTTP, de peticin respuesta se componen de:


La peticin contiene un mtodo HTTP (GET y POST.), un recurso o URL y los
parmetros o argumentos.
Una respuesta contiene un cdigo de estado o resultado, tipo del contenido de
la respuesta y el contenido como tal.

Se han estudiado los mtodos GET y POST para las solicitudes de recursos
estticos y dinmicos a un servidor de aplicaciones, su formato tanto en las
peticiones como en las respuestas y la utilizacin de sniffers para poder depurar
las solicitudes.

HTML es el lenguaje mediante el cual definimos los contenidos que fluyen por
Internet, conocidas como pginas HTML o pginas Web. Bsicamente se trata de
un lenguaje de etiquetado, que define la estructura y el contenido de un documento
a ser compartido y accedido en Internet a travs de un navegador web.
Una etiqueta es un elemento que define qu o como se debe presentar la
informacin que viene a tras la etiqueta, dentro de una pgina web.

Una pgina HTML, es un fichero de texto con extensin *.htm o *.html que
contiene una informacin formateada mediante el lenguaje HTML. Est formada
normalmente por una cabecera <HEAD> y un cuerpo <BODY>.

Un formulario (FORM) es la presentacin visual de entrada de datos en una


pgina HTML para ser enviados a una aplicacin servidora. Se han estudiado
distintos elementos como INPUT, TEXTAREA .
67

68

Unidad de Aprendizaje 4

JAVA SERVLETS

NDICE
4.1

Introduccin ................................................................... 71

4.2

Mi primer Java Servlet .................................................. 72

4.3

Java Servlets .................................................................. 84


4.3.1 El ciclo de vida de un Java Servlet ..............................84
4.3.2 Peticin y respuesta de un Java Servlet .....................88
4.3.3 Procesamiento de un formulario HTML ......................93
4.3.4 Empaquetado y despliegue ..........................................97

RECORDAR............................................................................. 103

MDULO B Unidad 4: Java Servlets

4.1

Introduccin

Ya vimos en la primera unidad del curso, que los Java Servlets eran un tipo de componente
Java EE que se empaquetaba en un mdulo web (WAR) y se desplegaba y ejecutaba en el
contenedor web de un Servidor de Aplicaciones Java EE.
Adicionalmente, dentro del patrn de diseo MVC ocupaban el espacio del Controlador, como
receptor/validador de peticiones, seleccionador de la lgica a ejecutar, y seleccionador de la
vista a presentar como resultado.

No obstante, de momento, dado que es el primer componente que vamos a estudiar, va a


cubrir completamente todas las responsabilidades del MVC. Y segn vayamos avanzando en
el curso, le iremos quitando responsabilidades que no debieran ser del Java Servlet, para
drselas a otro tipo de componente como la JavaServer Page (JSP).

Repetimos, esto es un mal diseo y una mala prctica de programacin. Pero consideramos
que es imprescindible ir aprendiendo poco a poco. Por tanto, este diseo es temporal
mientras avanzamos en las sucesivas unidades del curso.

71

Por ltimo, desde un punto de vista del lenguaje de programacin Java, un Java Servlet no es
ms que una clase Java que implementa una determinada interface definida en las
especificaciones.

4.2

Mi primer Java Servlet

Antes de entrar a estudiar en profundidad los Java Servlets, vamos a guiar los pasos para
desarrollar nuestro primer Java Servlet con Eclipse IDE for Java EE Developers y desplegarlo
en Apache Tomcat. Es requisito indispensable, haber seguido los pasos de instalacin y
configuracin de ambas dos herramientas detallados en la unidad 2 de este curso.
Estos mismos pasos nos servirn para los sucesivos ejemplos y actividades del resto del
curso.
Arrancamos Eclipse IDE for Java EE Developers y mediante el las opciones de men File ->
New -> Dynamic Web Project:

Creamos la estructura de desarrollo de un mdulo web (WAR). Como nombre del proyecto,
pondremos HolaMundoWeb, y nos aseguraremos que seleccionamos Apache Tomcat v7.0
72

MDULO B Unidad 4: Java Servlets


como entrono de ejecucin y 3.0 como el nivel de especificaciones Java EE (en cuanto a
contenedor web) que queremos utilizar. Pulsamos el botn Next dos veces:

En la ltima ventana del asistente, antes de pulsar el botn Finish, nos aseguramos de
marcar la opcin Generate web.xml deployment descriptor:

73

La estructura del proyecto creado debera ser algo as:

74

MDULO B Unidad 4: Java Servlets

En el directorio /Java Resources/src es donde iremos colocando el cdigo fuente de nuestras


clases Java.
En el directorio /WebContent es donde iremos colocando los recursos web, como por
ejemplo, las pginas HTML, las JavaServer Pages (JSP), imgenes, etc
Y el fichero web.xml de /WebContent/WEB-INF es el descriptor de despliegue del mdulo web
(en nuestro caso, del proyecto HolaMundoWeb).
Ahora crearemos un Java Servlet. Botn derecho sobre el nuevo proyecto -> New ->
Class:

75

En la siguiente ventana, rellenamos el nombre del paquete Java (Package) con


es.aulamentor, el nombre de la clase Java (Name) con HolaMundoServlet y la clase padre
(Superclass) con javax.servlet.http.HttpServlet.
Nota: No incluir las comillas en los nombres mencionados
Y pulsamos el botn Finish:

76

MDULO B Unidad 4: Java Servlets

Escribimos el siguiente cdigo Java en la clase creada y salvamos:


packagees.aulamentor;

importjava.io.IOException;
importjava.io.PrintWriter;

importjavax.servlet.ServletException;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;

publicclassHolaMundoServletextendsHttpServlet
{
protectedvoiddoGet(HttpServletRequestreq,HttpServletResponse
resp)throwsServletException,IOException
{
resp.setContentType("text/html;charset=UTF8");
PrintWriterout=resp.getWriter();
77

out.println("<!DOCTYPEHTMLPUBLIC\"//W3C//DTDHTML4.01
Transitional//EN\">");
out.println("<HTML>");
out.println("<HEAD>");
out.println("<TITLE>HolaMundo!</TITLE>");
out.println("</HEAD>");
out.println("<BODY>");
out.println("HolaMundo!");
out.println("</BODY>");
out.println("</HTML>");
}
}
No nos preocupemos en este momento por no entender el cdigo. De momento, simplemente
queremos mostrar los pasos para el desarrollo y despliegue de un Java Servlet. En los
sucesivos apartados iremos entendiendo el por qu de cada lnea.
A continuacin, editaremos el descriptor de despliegue del mdulo web, el fichero web.xml de
/WebContent/WEB-INF y aadiremos este cdigo XML salvando al final el fichero:
<?xmlversion="1.0"encoding="UTF8"?>
<webappxmlns:xsi="http://www.w3.org/2001/XMLSchemainstance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/webapp_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/webapp_3_0.xsd"id="WebApp_ID"
version="3.0">
<servlet>
<servletname>HolaMundoServlet</servletname>
<servletclass>es.aulamentor.HolaMundoServlet</servletclass>
</servlet>
<servletmapping>
<servletname>HolaMundoServlet</servletname>
<urlpattern>/HolaMundoServlet</urlpattern>
</servletmapping>
</webapp>
Ya solo queda, probar la aplicacin. Para ello, pulsamos el botn derecho sobre la clase del
Java Servlet -> Run As -> Run on Server:

78

MDULO B Unidad 4: Java Servlets

En la siguiente ventana, seleccionar Tomcat v7.0 Server at localhost y pulsar el botn


Finish:

79

En la vista de Console veremos las trazas que va dejando el Servidor de Aplicaciones Java
EE al arrancar, cmo despliega la aplicacin y automticamente abre un navegador interno de
Eclipse IDE con la URL: http://localhost:8080/HolaMundoWeb/HolaMundoServlet donde se ve
el resultado de nuestro primer Java Servlet:

80

MDULO B Unidad 4: Java Servlets

Perfectamente podramos utilizar otro navegador web (tipo Mozilla Firefox o Internet Explorer)
y escribir la misma URL. El comportamiento debera ser el mismo.
Para abrir el navegador interno de Eclipse IDE a mano, utilizar el botn de la barra de
herramientas:

Otra opcin tambin vlida habra sido utilizar el asistente de Java Servlets directamente en
vez del asistente de una clase Java convencional, pero preferamos que se viera un ejemplo a
mano. Esta opcin, habra sido con las opciones de men New -> Servlet:

81

Este asistente, aade una anotacin especial sobre la clase Java en el cdigo fuente de
manera que no es necesario aadir nada al descriptor de despliegue. Como ya comentamos
en la primera unidad, esta era una novedad de la ltima versin de la especificacin Java EE.
En este curso, comentaremos ambas dos opciones.
Ya solo nos queda desinstalar la aplicacin mediante la opcin Add and Remove:

82

MDULO B Unidad 4: Java Servlets

Y apagar el servidor mediante la opcin Stop:

83

4.3

Java Servlets

Todas las clases Java relacionadas con los Java Servlets, estn en los paquetes:

Los

javax.servet

javax.servlet.http
Java

Servlets

fueron

concebidos

para

ser

independientes

del

protocolo

de

comunicaciones. Pero la realidad ha sido, que el 99% de su uso est relacionado con el
protocolo HTTP (redes Internet e Intranets). De ah, que existan clases en el API que nos
ayudan a gestionar las peculiaridades de dicho protocolo en el segundo paquete mencionado:
javax.servlet.http
4.3.1 El ciclo de vida de un Java Servlet
Un Java Servlet tiene definido un ciclo de vida, forzado por la interface javax.servlet.Servlet,
por tanto, siempre que queramos implementar un Java Servlet, nuestra clase deber

84

MDULO B Unidad 4: Java Servlets


implementar dicho interface. Es una especie de contrato entre el Java Servlet y el
contenedor web del Servidor de Aplicaciones Java EE para poder funcionar.
Dicho ciclo de vida tiene los siguientes estados:
Cuando se recibe una peticin de la ejecucin de un Java Servlet en el Servidor de
Aplicaciones Java EE y este no ha sido invocado nunca, el contenedor web instancia
la clase del Java Servlet (llama a su constructor) y acto seguido invoca el mtodo:
public void init(ServletConfig config);
Dicho mtodo, solo se ejecuta una vez en la vida del Java Servlet y se suele utilizar
para llevar a cabo todas las labores de inicializacin que necesitemos para su
posterior ejecucin.
Como se puede observar, recibe como parmetro una instancia de la clase
ServletConfig, que representa informacin de configuracin que el administrador del
Servidor de Aplicaciones Java EE haya podido aadir. Veremos este mtodo en ms
detalle en los siguientes apartados.
Una vez est ya inicializado, entonces invoca el mtodo:
public void service(ServletRequest request, ServletResponse response);
Dicho mtodo se ejecuta cada vez que se recibe una peticin para este java Servlet.
En su implementacin, colocaremos la lgica para la que se cre dicho Java Servlet.
Como se puede observar, recibe como parmetros un par de instancias de las clases
ServletRequest y ServletResponse. Ambos dos parmetros representan la peticin (la
usaremos para entender qu nos estn pidiendo) y la respuesta (la utilizaremos para
devolver el resultado de la ejecucin del java Servlet al peticionario).
Si por alguna razn el contenedor web necesita eliminar al Java Servlet (se detiene el
Servidor de Aplicaciones Java EE, se queda sin recursos de memoria y necesita liberar
espacio, etc), entonces invoca el mtodo:
public void destroy();
Dicho mtodo solo se ejecuta una vez en la vida del java Servlet y se suele utilizar para
liberar todos aquellos recursos que pudiramos estar utilizando, para dejar el sistema
lo mas limpio posible.
Lo que ocurre, es que el API ya tiene una serie de clases que no solo implementan por
defecto el ciclo completo de vida de un Java Servlet, sino que como decamos, tambin nos
ayuda con los temas relacionados con el protocolo HTTP.
As, tenemos la clase javax.servlet.http.HttpServlet que adems de implementar los mtodos
comentados anteriormente (es decir, implementar el interface javax.servlet.Servlet), aade
otros ms potentes que nos dan valor aadido al trabajar con el protocolo HTTP.

85

Por ejemplo, si recordamos de la unidad anterior donde hablbamos del protocolo HTTP,
comentbamos que existan distintos mtodos utilizables en la peticin: GET, POST, PUT,
etc
Pues esta clase, implementa un mtodo Java por cada mtodo HTTP existente, de forma,
qu l ya se encarga de recibir la peticin HTTP, examinarla, e invocar el mtodo Java
correspondiente al mtodo HTTP utilizado, as como darnos acceso a un par de objetos que
representan tanto la peticin como la respuesta HTTP. Los ms habituales que utilizaremos
nosotros son:

protected void doGet(HttpServletRequest request, HttpServletResponse response);

protected void doPost(HttpServletRequest request, HttpServletResponse response);

Dichos mtodos normalmente los sobrescribiremos en nuestro Java Servlet para incluir
nuestra lgica particular.
Veamos un ejemplo de un Java Servlet que simplemente muestra por la consola del Servidor
de Aplicaciones Java EE trazas del ciclo de vida:
packagees.aulamentor;

importjava.io.IOException;
importjavax.servlet.ServletConfig;
importjavax.servlet.ServletException;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;

publicclassCicloDeVidaServletextendsHttpServlet
{
publicCicloDeVidaServlet()
{
super();
System.out.println("CicloDeVidaServlet()");
}

publicvoidinit(ServletConfigconfig)throwsServletException
{
System.out.println("init()");
}

publicvoiddestroy()
{
System.out.println("destroy()");
}

protectedvoiddoGet(HttpServletRequestrequest,HttpServletResponse
response)throwsServletException,IOException
{
System.out.println("doGet()");
}
}
El editor de despliegue tendra algo as:

86

MDULO B Unidad 4: Java Servlets


<?xmlversion="1.0"encoding="UTF8"?>
<webappxmlns:xsi="http://www.w3.org/2001/XMLSchemainstance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/webapp_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/webapp_3_0.xsd"id="WebApp_ID"
version="3.0">
<servlet>
<servletname>CicloDeVidaServlet</servletname>
<servletclass>es.aulamentor.CicloDeVidaServlet</servletclass>
</servlet>
<servletmapping>
<servletname>CicloDeVidaServlet</servletname>
<urlpattern>/CicloDeVidaServlet</urlpattern>
</servletmapping>
</webapp>
Al invocar varias veces a este Java Servlet desde un navegador, y despus parar el Servidor
de Aplicaciones Java EE, deberamos ver algo as:

Como podemos ver, en la consola salen en negro las trazas que dejamos desde nuestro
cdigo: primero el constructor, seguido del init(), seguido de tres doGet() porque ese fue el
87

nmero de veces que invocamos seguidas el Java Servlet, y por ltimo, al apagar el Servidor
de Aplicaciones Java EE el destroy().
En el navegador, evidentemente no se ve nada, puesto que no devolvimos ningn resultado
en el cdigo del Java Servlet.

4.3.2 Peticin y respuesta de un Java Servlet


La invocacin de un Java Servlet independientemente del mtodo HTTP que se utilice,
siempre

recibe

dos

parmetros:

javax.servlet.http.HttpServletRequest

javax.servlet.http.HttpServletResponse.
javax.servlet.http.HttpServletRequest, es un interfaz que define cmo interactuar con la
informacin que viene en una peticin HTTP, como por ejemplo, las cabeceras HTTP de la
peticin, los parmetros de la peticin, etc
Algunos mtodos son:
java.util.Enumeration<java.lang.String> getParameterNames(): devuelve una coleccin
con los nombres de todos los parmetros enviados en la peticin.
java.lang.String getParameter(java.lang.String name): devuelve el valor de un
parmetro concreto enviado en la peticin.
java.lang.String[] getParameterValues(java.lang.String name): devuelve todos los
valores de un parmetro concreto enviado en la peticin (imaginemos un conjunto de
checkboxes con el mismo nombre de un formulario).
java.util.Enumeration<java.lang.String> getAttributeNames(): devuelve una coleccin
con los nombres de todos los atributos de la peticin.
java.lang.Object getAttribute(java.lang.String name): devuelve el valor de un atributo
concreto de la peticin.
java.util.Enumeration<java.lang.String> getHeaderNames(): devuelve una coleccin
con los nombres de todas las cabeceras HTTP enviadas en la peticin.
java.lang.String getHeader(java.lang.String name): devuelve el valor de una cabecera
HTTP concreta de la peticin.
java.lang.String getContextPath(): devuelve la porcin de URL de la peticin que
corresponde al ContextPath. El ContextPath es el identificador que utiliza el Servidor
de aplicaciones Java EE para diferenciar una aplicacin u otra. Siempre va en la URL
por delante del recurso pedido como tal.
Existen muchos mtodos ms, algunos muy importantes para el manejo de la Sesin HTTP
y de las Cookies (los veremos en la siguiente unidad), para redireccionar la peticin a otro
java Servlet o JavaServer Page (tambin los veremos en una unidad posterior) y otros
88

MDULO B Unidad 4: Java Servlets


muchos para acceder a ms informacin disponible en una peticin HTTP que podemos ver
en el siguiente ejemplo:
packagees.aulamentor;

importjava.io.IOException;
importjava.util.Enumeration;

importjavax.servlet.ServletException;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;

publicclassRequestServletextendsHttpServlet
{
protectedvoiddoGet(HttpServletRequestrequest,HttpServletResponse
response)throwsServletException,IOException
{
System.out.println("ContextPath:"+request.getContextPath());
System.out.println("LocalAddr:"+request.getLocalAddr());
System.out.println("LocalName:"+request.getLocalName());
System.out.println("LocalPort:"+request.getLocalPort());
System.out.println("Method:"+request.getMethod());
System.out.println("Protocol:"+request.getProtocol());
System.out.println("QueryString:"+request.getQueryString());
System.out.println("RemoteAddr:"+request.getRemoteAddr());
System.out.println("RemoteHost:"+request.getRemoteHost());
System.out.println("RemotePort:"+request.getRemotePort());
System.out.println();
Enumeration<String>headers=request.getHeaderNames();
while(headers.hasMoreElements())
{
Stringheader=headers.nextElement();
System.out.println(header+":"+request.getHeader(header));
}
System.out.println();
Enumeration<String>parameters=request.getParameterNames();
while(parameters.hasMoreElements())
{
Stringparameter=parameters.nextElement();
System.out.println(parameter+":"+
request.getParameter(parameter));
}
}
}
Y el descriptor de despliegue:
<?xmlversion="1.0"encoding="UTF8"?>
<webappxmlns:xsi="http://www.w3.org/2001/XMLSchemainstance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/webapp_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/webapp_3_0.xsd"id="WebApp_ID"
version="3.0">
<servlet>
<servletname>RequestServlet</servletname>
<servletclass>es.aulamentor.RequestServlet</servletclass>
</servlet>
<servletmapping>
89

<servletname>RequestServlet</servletname>
<urlpattern>/RequestServlet</urlpattern>
</servletmapping>
</webapp>
Si en el navegador utilizamos la siguiente URL para invocar el Java Servlet:
http://localhost:8080/EjemplosWeb/RequestServlet?param1=valor1&param2=valor2
Nota: Fijaros, que hemos aadido dos parmetros en la URL.
En la consola del Servidor de Aplicaciones Java EE deberamos ver algo como esto (en cada
caso depender un poco del entorno utilizado):

En el API Java EE, estn detallados todos los mtodos:


http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html
javax.servlet.http.HttpServletResponse, es un interfaz que define cmo trabajar y generar la
respuesta HTTP desde el Java Servlet, como por ejemplo, acceder al stream de escritura,
especificar el tipo y longitud del contenido, etc
Algunos mtodos son:
java.io.PrintWriter getWriter() throws java.io.IOException: nos devuelve una referencia
al objeto de escritura en modo carcter de la respuesta, a travs del cual escribiremos.
ServletOutputStream getOutputStream() throws java.io.IOException: nos devuelve una
referencia al objeto de escritura en modo byte de la respuesta, a travs del cual
escribiremos. La diferencia con el anterior es el modo de escritura: carcter o byte.
90

MDULO B Unidad 4: Java Servlets


void setContentType(java.lang.String type): nos sirve para especificar el tipo de
contenido que vamos a enviar en la respuesta. Por ejemplo: text/html, text/plain,
image/gif, etc Los distintos tipos de contenido estn estandarizados a travs de las
especificaciones MIME (Multipurpose Internet Mail Extensions). En la siguiente URL
estn documentados todos los posibles tipos:
http://www.iana.org/assignments/media-types/index.html
Recordemos de la tercera unidad de este manual, cuando hablbamos del protocolo
HTTP, que esta era una informacin que viajaba en la cabecera de una respuesta
HTTP. Los siguientes mtodos, tambin sirven para aadir informacin especfica de
una respuesta HTTP.
void setContentLength(int len): nos sirve para especificar la longitud del cuerpo de la
respuesta
void setStatus(int sc): nos sirve para devolver un cdigo de estado HTTP.
void sendError(int sc, java.lang.String msg) throws java.io.IOException: nos sirve para
devolver un cdigo de error HTTP junto con un mensaje descriptivo.
Existen muchos mtodos ms, algunos muy importantes para el manejo de las Cookies (los
veremos en la siguiente unidad).
Veamos un ejemplo:
packagees.aulamentor;

importjava.io.File;
importjava.io.FileInputStream;
importjava.io.FileNotFoundException;
importjava.io.IOException;
importjava.io.OutputStream;

importjavax.servlet.ServletConfig;
importjavax.servlet.ServletException;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;

publicclassResponseServletextendsHttpServlet
{
privatebyte[]buffer=newbyte[0];

publicvoidinit(ServletConfigconfig)throwsServletException
{
try
{
Filefile=newFile("C:\\images\\duke.gif");
FileInputStreamin=newFileInputStream(file);
buffer=newbyte[(int)file.length()];
in.read(buffer);
in.close();
}
catch(FileNotFoundExceptionex)
91

{
ex.printStackTrace();
}
catch(IOExceptionex)
{
ex.printStackTrace();
}
}

protectedvoiddoGet(HttpServletRequestrequest,HttpServletResponse
response)throwsServletException,IOException
{
response.setContentType("image/gif");
response.setContentLength(buffer.length);
response.getOutputStream().write(buffer);
response.setStatus(200);
}
}
Y el descriptor de despliegue:
<?xmlversion="1.0"encoding="UTF8"?>
<webappxmlns:xsi="http://www.w3.org/2001/XMLSchemainstance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/webapp_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/webapp_3_0.xsd"id="WebApp_ID"
version="3.0">
<servlet>
<servletname>ResponseServlet</servletname>
<servletclass>es.aulamentor. ResponseServlet</servletclass>
</servlet>
<servletmapping>
<servletname>ResponseServlet</servletname>
<urlpattern>/ResponseServlet</urlpattern>
</servletmapping>
</webapp>
Si en el navegador utilizamos la siguiente URL para invocar el Java Servlet:
http://localhost:8080/EjemplosWeb/ResponseServlet
En el navegador deberamos ver la imagen que hemos utilizado en el ejemplo

En el API Java EE, estn detallados todos los mtodos:


92

MDULO B Unidad 4: Java Servlets


http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletResponse.html

4.3.3 Procesamiento de un formulario HTML


Hasta ahora, todos los ejemplos no han tenido interaccin real con el usuario. Vamos a ver
cmo sera un Java Servlet que procese una informacin recogida a travs de un formulario
HTML. Por ejemplo, una calculadora muy sencilla que simplemente sume dos nmeros.
Tendremos la siguiente pgina HTML:
<!DOCTYPEhtmlPUBLIC"//W3C//DTDHTML4.01Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<METAhttpequiv="ContentType"content="text/html;charset=ISO
88591">
<TITLE>Calculadora</TITLE>
</HEAD>
<BODY>
<FORMmethod="POST"action="/EjemplosWeb/SumadorServlet">
<TABLEborder="0">
<TR>

<TD>Primernmero:</TD>

<TD><INPUTname="param1"></TD>

</TR>

<TR>

<TD>Segundonmero:</TD>

<TD><INPUTname="param2"></TD>

</TR>

<TR>

<TD><INPUTtype="submit"value="Sumar"></TD>

</TR>

</TABLE>
</FORM>
</BODY>
</HTML>
Y el siguiente Java Servlet:
packagees.aulamentor;

importjava.io.IOException;
importjava.io.PrintWriter;

importjavax.servlet.ServletException;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;

publicclassSumadorServletextendsHttpServlet
{
protectedvoiddoGet(HttpServletRequestrequest,HttpServletResponse
response)throwsServletException,IOException
{
procesarPeticion(request,response);
}
93


protectedvoiddoPost(HttpServletRequestrequest,HttpServletResponse
response)throwsServletException,IOException
{
procesarPeticion(request,response);
}

privatevoidprocesarPeticion(HttpServletRequestrequest,
HttpServletResponseresponse)throwsServletException,IOException
{
response.setContentType("text/html;charset=UTF8");

try
{
intparam1=Integer.parseInt(request.getParameter("param1"));

intparam2=Integer.parseInt(request.getParameter("param2"));

intresult=param1+param2;

response.setStatus(200);

PrintWriterout=response.getWriter();

out.println("");

out.println("<!DOCTYPEHTMLPUBLIC\"//W3C//DTDHTML4.01
Transitional//EN\">");

out.println("<HTML>");

out.println("<HEAD>");

out.println("<TITLE>Calculadora</TITLE>");

out.println("</HEAD>");

out.println("<BODY>");

out.println("Elresultadodelasumaes:"+result);

out.println("<BR><BR>");

out.println("<Ahref=\"/EjemplosWeb/calculadora.html\">Volver
atrs...</A>");

out.println("</BODY>");

out.println("</HTML>");
}
catch(NumberFormatExceptionex)
{

response.sendError(500,"Algunodelosnmerosnocontenadgitos
vlidos...");
}
}
}
Nota: Recordar que los contenidos estticos como una pgina HTML se ubican dentro del
directorio /WebContent.
Al cargar la pgina en el navegador, deberamos ver algo as:

94

MDULO B Unidad 4: Java Servlets

Al introducir los nmeros 2 y 8 y pulsar el botn de Sumar, desde el navegador se lanzar


una peticin HTTP al Servidor de Aplicaciones Java EE pidiendo la ejecucin del Java
Servlet (que est en el mismo servidor que el HTML) con dichos parmetros y en el
navegador, deberamos ver algo as:

En caso de que no hubiramos introducido algn parmetro, o alguno de ellos llevase algn
carcter que no fuese un dgito, deberamos ver una pgina de error parecida a esta:

95

En la siguiente unidad, hablaremos un poco mas del tratamiento de errores. En este ejemplo,
hemos optado por mostrar una pgina de error HTTP, pero podramos perfectamente haber
contestado una pgina HTML al estilo de la que mostraba el resultado correcto, indicando
los motivos del error.
Aprovechando este ejemplo, vamos a comentar otro tema interesante. En la unidad donde
tratamos el protocolo HTTP, comentamos que la diferencia entre los mtodos HTTP GET y
POST era que uno enviaba los parmetros en la URL (GET) y otro en el cuerpo del mensaje
HTTP (POST). En este ejemplo, hemos utilizado el mtodo POST, pero fijaros lo que
veramos en la URL del navegador si en vez de POST hubiramos utilizado GET:
http://localhost:8080/EjemplosWeb/SumadorServlet?param1=2&param2=8

Por eso comentbamos, que lo habitual cuando se utilizan formularios es emplear el mtodo
POST para evitar mostrar al usuario URLs farragosas, adems de que por temas de
seguridad, se intente evitar que se lea en claro una contrasea (por ejemplo).

96

MDULO B Unidad 4: Java Servlets


4.3.4 Empaquetado y despliegue
Como comentbamos en la primera unidad de este curso de introduccin al Java EE, una
aplicacin Java EE est formada por un empaquetamiento de una o varias unidades
conocidas con el nombre de mdulos. Este empaquetamiento final era un EAR (Enterprise
ARchive).
Uno de los distintos tipos de mdulos mencionados son los mdulos Web, que contienen
normalmente Java Servlets, JavaServer Pages (JSP), JavaServer Faces (JSF), contenidos
estticos como imgenes, HTMLs, CSSs Su extensin del fichero empaquetado es WAR
(Web ARchive).
En este curso, nos vamos a centrar exclusivamente de este tipo de mdulos, ya que
intentamos cubrir solo la parte web de la programacin Java EE y no el resto de aspectos
que daran lugar a un curso demasiado extenso o a un segundo curso.
A pesar de que las aplicaciones Java EE se empaquetan en un EAR, los Servidores de
Aplicacin que solo cubren parte de la especificacin Java EE, como ocurre con Apache
Tomcat, permiten desplegar simplemente mdulos Web aislados. Este ser nuestro caso
durante este curso.
Grficamente, la estructura de un mdulo Web empaquetado sera la siguiente:

Como podemos observar, tiene bastante parecido a la estructura del proyecto web dentro
de Eclipse IDE for Java EE Developers aunque no es igual. En principio, el raz del fichero

97

WAR correspondera al directorio /WebContent y el directorio /classes del fichero WAR


correspondera al directorio /build/classes.
Ahora bien, normalmente no nos preocuparemos mucho de la generacin de un mdulo
Web u otro tipo de mdulo, porque son los IDEs los que nos van a ayudar a generarlo. Por
ejemplo, en nuestro caso, con Eclipse IDE for Java EE Developers basta con seleccionar el
proyecto, pulsar el botn derecho del ratn y seleccionar las opciones Export -> WAR
file:

98

MDULO B Unidad 4: Java Servlets


En la siguiente ventana, nos aseguramos que el proyecto seleccionado es el correcto, y
decidimos donde y con que nombre se va a generar el fichero WAR, por ejemplo,
C:\EjemplosWeb.war. Pulsar el botn Finish:

Si vamos a una sesin de DOS, mediante el comando de la JDK jar.exe (jar tvf
nombreFichero.war), podemos ver su contenido y confirmar que la estructura generada es
exactamente la de la especificacin Java EE:

99

Este fichero WAR, sera el que un administrador de Servidores de Aplicacin Java EE


desplegara y configurara para que la aplicacin estuviese disponible y dando servicio. Pero
en nuestro caso, simplemente aadiremos o quitaremos aplicaciones en el Apache Tomcat
de Eclipse IDE for Java EE Developers mediante el interfaz de usuario: botn derecho del
ratn y la opcin Add and Remove, o directamente sobre el componente y Run As ->
Run on Server.
Nos queda no obstante hablar un poco sobre el descriptor de despliegue. Como ya
adelantbamos en la primera unidad, se trata de un fichero XML donde se describe el
contenido y posible comportamiento del contenido del mdulo.
En el caso concreto de los mdulos Web, su descriptor de despliegue es el fichero web.xml
A lo largo de esta unidad, hemos visto en los ejemplos algunas etiquetas, pero ahora
hablaremos un poco ms despacio de algunas de ellas:
<?xmlversion="1.0"encoding="UTF8"?>
<webappxmlns:xsi="http://www.w3.org/2001/XMLSchemainstance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/webapp_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/webapp_3_0.xsd"id="WebApp_ID"
version="3.0">
<servlet>
<servletname>SumadorServlet</servletname>
<servletclass>es.aulamentor.SumadorServlet</servletclass>
</servlet>
<servletmapping>
<servletname>SumadorServlet</servletname>
<urlpattern>/SumadorServlet</urlpattern>
</servletmapping>
</webapp>
La primera lnea es obligatoria, y simplemente indica que el fichero es XML 1.0
Despus, viene el bloque web-app que es el que delimita el contenido del descriptor de
despliegue del mdulo Web. En la etiqueta de inicio, se aaden una serie de atributos entre
los cuales est la ubicacin del esquema XML que contiene la especificacin utilizada:
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd
Los bloques servlet y servlet-mapping son ms interesantes. Sirven para registrar los
Java Servlets que hay en el mdulo Web, y especificar la URL para cada uno de ellos. Por
ejemplo, en el descriptor de despliegue que hemos usado, decimos que hay un Java Servlet
que

llamamos

SumadorServlet

que

est

implementado

en

la

clase

Java

es.aulamentor.SumadorServlet y que su URL es /SumadorServlet.


Si no tuviramos esos dos bloques en el descriptor de despliegue, el Servidor de
Aplicaciones Java EE nos devolvera un error HTTP 404 que significaba que el recurso
solicitado no existe. Veamos el error visualmente:

100

MDULO B Unidad 4: Java Servlets

Aunque el Java Servlet vaya en el mdulo Web, si no est especificado en el descriptor de


despliegue, el Servidor de Aplicaciones Java EE no lo sabe identificar.
Existen muchas ms etiquetas a utilizar en un descriptor de despliegue de un mdulo Web,
pero las iremos viendo a lo largo del curso segn las vayamos necesitando. De momento
nos quedamos con la general web-app y las necesarias para registrar e identificar un Java
Servlet.
No obstante, muchos recordaris que en la primera unidad comentbamos que con la ltima
especificacin Java EE, haba aparecido la opcin de obviar los descriptores de despliegue
a cambio de anotar el cdigo fuente con unas anotaciones especiales. Esta es otra opcin,
en cuyo caso no hace falta ni tener fsicamente el fichero web.xml
Una anotacin se identifica precedindola del carcter @ (arroba) y acompaa a la definicin
de una clase, de un atributo o de un mtodo Java. Al igual que ocurre con las etiquetas del
descriptor de despliegue, hay muchas anotaciones, pero las iremos viendo poco a poco a lo
largo del curso.
De momento, para sustituir a los bloques servlet y servlet-mapping que como hemos
visto registran y definen un Java Servlet, existe la anotacin:
@WebServlet
Que puede aadir atributos entre parntesis para complementar si definicin.
En nuestro caso, el cdigo fuente Java de nuestro Java Servlet sera algo as:
....
importjavax.servlet.annotation.WebServlet;
....
@WebServlet(name="SumadorServlet",urlPatterns={"/SumadorServlet"})
publicclassSumadorServletextendsHttpServlet
{
....
}
Mediante la anotacin, al desplegar el mdulo Web en el Servidor de Aplicaciones Java EE,
estamos registrando un Java Servlet que se llama SumadorServlet, cuya URL es
/SumadorServlet.
101

Todos los posibles atributos de la anotacin @WebServlet estn en el API:


http://docs.oracle.com/javaee/6/api/javax/servlet/annotation/WebServlet.html
Si nuestro Java Servlet est desarrollado haciendo uso de la anotacin, entonces no hace
falta que lo registremos en el descriptor de despliegue. Incluso, si el descriptor de
despliegue solo llevaba esa informacin, podemos prescindir de l.
Ambas dos opciones pueden convivir en un mismo mdulo Web, es decir, podemos
describir algunas cosas en el descriptor de despliegue, y otras mediante anotaciones,
aunque normalmente no es una buena prctica el mezclar las dos opciones. Normalmente
se utiliza una u otra.
Y cul es mejor utilizar? Pues depende. Normalmente los desarrolladores prefieren las
anotaciones porque les es ms rpido el desarrollo, pero los administradores de sistemas
prefieren los descriptores de despliegue porque les permite entender el contenido de un
mdulo web sin necesidad de saber interpretar cdigo fuente (cdigo fuente que en
ocasiones no tienen a su disposicin debido a que solo reciben los bytecodes de las clases
Java).
A lo largo del curso, iremos explicando siempre ambas dos opciones.

102

RECORDAR

Los Java Servlets son un tipo de componente Java EE que se empaquetan en un


mdulo web (WAR) y se despliegan y ejecutan en el contenedor web de un Servidor
de Aplicaciones Java EE.

Adicionalmente, dentro del patrn de diseo MVC ocupan el espacio del


Controlador, como receptor/validador de peticiones, seleccionador de la lgica a
ejecutar, y seleccionador de la vista a presentar como resultado

Los Java Servlets siempre deben de implementar la interface javax.servlet.Servlet


o heredar de la clase javax.servlet.http.HttpServlet.

El ciclo de vida viene determinado por los siguientes mtodos


init: se ejecuta una vez en la vida del Java Servlet y se suele utilizar para llevar a
cabo todas las labores de inicializacin que necesitemos para su posterior
ejecucin.
service: se ejecuta cada vez que se recibe una peticin para el Java Servlet. En
su implementacin, se coloca la lgica para la que se cre. Si se ha heredado de
la clase javax.servlet.http.HttpServlet, se utilizan los mtodos doGet o doPost.

destroy: se ejecuta una vez en la vida del Java Servlet y se suele utilizar para
liberar todos aquellos recursos que pudiramos haber utilizado, con el afn de
dejar el sistema lo ms limpio posible.

Los

objetos

de

los

tipos

javax.servlet.http.HttpServletRequest

javax.servlet.http.HttpServletResponse. que reciben los mtodos doGet y


doPost, se utilizan para identificar la peticin realizada y la respuesta dada.
Contienen mtodos para obtener de la peticin parmetros, atributos, cabeceras
poner en la respuesta la respuesta en si misma, su longitud, el estado de la peticin

103

Hemos aprendido que la principal diferencia entre las peticiones GET y POST es
que en las primeras el paso de parmetros es apreciable en la URL. Para poder
utilizar el POST, se utilizan los formularios (FORM) de HTML.

Para poder desplegar una aplicacin web, se puede realizar mediante un EAR o un
WAR (dependiendo del servidor de aplicaciones). El descriptor de despliegue
web.xml, aunque no es obligatorio si se utilizan anotaciones, conviene que exista
para poder determinar de una manera sencilla que es lo que se va a desplegar y el
comportamiento asociado.

104

Unidad de Aprendizaje 5

JAVASERVER PAGES

NDICE
5.1

Introduccin ................................................................. 107

5.2

Mi primer JavaServer Page ........................................ 108

5.3

JavaServer Pages ........................................................ 118


5.3.1 Etiqueta de comentario................................................119
5.3.2 Etiqueta de directiva.....................................................119
5.3.3 Etiqueta de declaracin ...............................................120
5.3.4 Etiqueta de scriptlets ...................................................121
5.3.5 Etiqueta de expresin ..................................................122
5.3.6 Ejemplo con todas las etiquetas ................................123

5.4

Otros conceptos .......................................................... 127


5.4.1 El ciclo de vida de un JavaServer Page ....................127
5.4.2 Objetos implcitos de un JavaServer Page...............128
5.4.3 Empaquetado y despliegue ........................................129

PARA RECORDAR.................................................................. 134

MDULO B Unidad 5: JavaServer Pages

5.1

Introduccin

Ya vimos en la primera unidad del curso, que los JavaServer Pages, tambin conocidos por su
acrnimo JSP, eran un tipo de componente Java EE que se empaquetaba en un mdulo web
(WAR) y se desplegaba y ejecutaba en el contenedor web de un Servidor de Aplicaciones Java
EE.
Adicionalmente, dentro del patrn de diseo MVC ocupaban el espacio de la Vista, como
encargado de mostrar el resultado de la peticin al usuario final. Es decir, al contrario que los
Java Servlets, estas estn enfocadas a la presentacin.

No obstante, de momento, va a cubrir completamente todas las responsabilidades del MVC.


Y segn vayamos avanzando en el curso, le iremos quitando responsabilidades que no
debieran ser del JavaServer Page, para drselas a otro tipo de componente como los Java
Servlets.

Repetimos, esto es un mal diseo y una mala prctica de programacin. Pero consideramos
que es imprescindible ir aprendiendo poco a poco. Por tanto, este diseo es temporal
mientras avanzamos en las sucesivas unidades del curso.

107

Por ltimo, desde un punto de vista del lenguaje de programacin Java, una JavaServer Page
no es ms que un fichero con un lenguaje de etiquetado como HTML y trozos de cdigo Java
embebidos.

5.2

Mi primer JavaServer Page

Antes de entrar a estudiar en profundidad los JavaServer Pages, vamos a guiar los pasos para
desarrollar nuestro primer JavaServer Page con Eclipse IDE for Java EE Developers y
desplegarlo en Apache Tomcat. Es requisito indispensable, haber seguido los pasos de
instalacin y configuracin de ambas dos herramientas detallados en la unidad 2 de este
curso.
Estos mismos pasos nos servirn para los sucesivos ejemplos y actividades del resto del
curso.
Arrancamos Eclipse IDE for Java EE Developers y mediante el las opciones de men File ->
New -> Dynamic Web Project:

108

MDULO B Unidad 5: JavaServer Pages


Creamos la estructura de desarrollo de un mdulo web (WAR). Como nombre del proyecto,
pondremos HolaMundoWeb, y nos aseguraremos que seleccionamos Apache Tomcat v7.0
como entrono de ejecucin y 3.0 como el nivel de especificaciones Java EE (en cuanto a
contenedor web) que queremos utilizar. Pulsamos el botn Next dos veces:

En la ltima ventana del asistente, antes de pulsar el botn Finish, nos aseguramos de
marcar la opcin Generate web.xml deployment descriptor:

109

La estructura del proyecto creado debera ser algo as:

110

MDULO B Unidad 5: JavaServer Pages

En el directorio /Java Resources/src es donde iremos colocando el cdigo fuente de nuestras


clases Java.
En el directorio /WebContent es donde iremos colocando los recursos web, como por
ejemplo, las pginas HTML, las JavaServer Pages, imgenes, etc
Y el fichero web.xml de /WebContent/WEB-INF es el descriptor de despliegue del mdulo web
(en nuestro caso, del proyecto HolaMundoWeb).
Ahora crearemos un JavaServer Page. Botn derecho sobre el nuevo proyecto -> New ->
JSP File:

111

En la siguiente ventana, rellenamos el nombre del fichero (File name) con HolaMundo.jsp.
Nos aseguraremos de que el directorio donde se va a crear sea /WebContent (normalmente se
selecciona por defecto). Y pulsamos el botn Finish:

112

MDULO B Unidad 5: JavaServer Pages

Escribimos el siguiente cdigo y salvamos:


<%@pagelanguage="java"contentType="text/html;charset=ISO88591"
pageEncoding="ISO88591"%>
<!DOCTYPEhtmlPUBLIC"//W3C//DTDHTML4.01Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<METAhttpequiv="ContentType"content="text/html;charset=ISO
88591">
<TITLE>HolaMundo!</TITLE>
</HEAD>
<BODY>
HolaMundo!
</BODY>
</HTML>
No nos preocupemos en este momento por no entender el cdigo. De momento, simplemente
queremos mostrar los pasos para el desarrollo y despliegue de un JavaServer Page. En los
sucesivos apartados iremos entendiendo el por qu de cada lnea.
113

Ya solo queda, probar la aplicacin. Para ello, pulsamos el botn derecho sobre el fichero JSP
-> Run As -> Run on Server:

En la siguiente ventana, seleccionar Tomcat v7.0 Server at localhost y pulsar el botn


Finish:

114

MDULO B Unidad 5: JavaServer Pages

En la vista de Console veremos las trazas que va dejando el Servidor de Aplicaciones Java
EE al arrancar, cmo despliega la aplicacin y automticamente abre un navegador interno de
Eclipse IDE con la URL: http://localhost:8080/HolaMundoWeb/HolaMundo.jsp donde se ve el
resultado de nuestro primer JavaServer Page:

115

Perfectamente podramos utilizar otro navegador web (tipo Mozilla Firefox o Internet Explorer)
y escribir la misma URL. El comportamiento debera ser el mismo.
Para abrir el navegador interno de Eclipse IDE a mano, utilizar el botn de la barra de
herramientas:

Ya solo nos queda desinstalar la aplicacin mediante la opcin Add and Remove:

116

MDULO B Unidad 5: JavaServer Pages

Y apagar el servidor mediante la opcin Stop:

117

5.3

JavaServer Pages

Una JavaServer Page, es un fichero de extensin *.jsp que utiliza principalmente lenguajes de
etiquetado como el HTML (estudiado en la unidad 3) u otros menos extendidos como WML,
SVG, cHTML, etc, en el que se pueden embeber mediante unas etiquetas especiales, cdigo
Java.
Es decir, vendran a ser como el opuesto de los Java Servlets. Si aquellos eran cdigo Java
con cdigo de etiquetado embebido en las sentencias de escritura, estas son cdigo de
etiquetado con cdigo Java embebido.
A la hora de su ejecucin, el Servidor Java EE convertir estos ficheros en un Java Servlet
como los estudiados en la unidad anterior. Es decir, generar de forma automtica, un Java
Servlet en el que incluir todos los fragmentos de Java embebidos, y aadir sentencias de
impresin con el lenguaje de etiquetado de presentacin esttico.
Aunque como decimos, este proceso ocurre a sin conocimiento directo del desarrollador y lo
realiza automticamente el Servidor de Aplicaciones Java EE, siempre va bien tenerlo en
118

MDULO B Unidad 5: JavaServer Pages


cuenta para entender correctamente el significado de las etiquetas especficas de las
JavaServer Pages.
Existen unas cuantas etiquetas especficas de las JavaServer Pages, que nada tienen que ver
con el lenguaje de etiquetado que se est utilizando para la presentacin, y son las que
estudiaremos a continuacin como parte de la sintaxis.

5.3.1 Etiqueta de comentario


Los comentarios en una JavaServer Page se aaden delimitados por las siguientes dos
etiquetas de inicio y fin:
<%-- Comentario --%>
Dichos comentarios, no se envan como parte de la respuesta desde el Servidor Java EE. Es
decir, no es informacin que viaje por la red y por tanto no afectan al volumen de
informacin transferido.
Veamos un ejemplo:
<%@pagelanguage="java"contentType="text/html;charset=ISO88591"
pageEncoding="ISO88591"%>
<!DOCTYPEhtmlPUBLIC"//W3C//DTDHTML4.01Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<METAhttpequiv="ContentType"content="text/html;charset=ISO
88591">
<TITLE>HolaMundo!</TITLE>
</HEAD>
<BODY>
<%MiprimerapginaJSP%>
HolaMundo!
</BODY>
</HTML>
Al ejecutar el ejemplo, en el navegador no veris nada distinto. Y si al navegador se le pide
ver el cdigo fuente de la pgina HTML que ha cargado, tampoco veris ninguna de las
etiquetas relacionadas con las JavaServer Pages.

5.3.2 Etiqueta de directiva


Las etiquetas de directiva siguen la siguiente sintaxis:
<%@ directiva [atributo=valor] %>
Existen tres tipos de directivas. De hecho, en los ejemplos anteriores ya hemos utilizado una
de ellas: page, como primera lnea de la JavaServer Page.
Los tres tipos son:

119

page: aade informacin tcnica a la pgina utilizada por el Servidor de Aplicaciones


Java EE para su posterior conversin a un Java Servlet.
Puede utilizar mltiples atributos, pero los ms extendidos e importantes son:
o contentType: para identificar el contenido.
o pageEncoding: para identificar el juego de caracteres utilizado.
o import: fundamental para poder importar las clases Java utilizadas en los
trozos de cdigo java embebido y poder compilar correctamente.
o Otras como errorPage, isThreadSafe o session, que veremos en siguientes
unidades.
Veamos un ejemplo:
<%@pagecontentType="text/html;charset=ISO88591"
pageEncoding="ISO88591"%>
<%@pageimport="java.util.Date,es.aulamentor.*"%>
include: se utiliza para incluir en ese punto el resultado de la ejecucin de otra
JavaServer Page. Dichas JavaServer Pages suelen ser fragmentos de una
presentacin, por ejemplo, una cabecera, un mensaje de copyright, etc. Es muy til
para reutilizar cdigo y no tener que escribirlo n veces, adems de facilitar su posterior
mantenimiento.
Utiliza un nico atributo que es file, para identificar la JavaServer Page a incluir.
Veamos un ejemplo:
<%@includefile="cabecera.jsp%>
taglib: se utiliza para definir una librera de etiquetas (tags) propia que se va a utilizar
en la JavaServer Page. La estudiaremos en siguientes unidades.
No obstante, veamos un ejemplo:
<%@tagliburi="http://java.sun.com/jsp/jstl/core"prefix="c"%>

5.3.3 Etiqueta de declaracin


En una JavaServer Page, es posible definir atributos y mtodos, como si de una clase Java
se tratase, que sern accesibles desde toda la JavaServer Page.
Dichas declaraciones se realizan mediante las etiquetas:
<%! %>
Por ejemplo, si queremos definir un atributo de tipo java.lang.String con el valor Hola
Mundo! lo haramos as:
120

MDULO B Unidad 5: JavaServer Pages


<%!Stringvar=HolaMundo!%>
El Servidor de Aplicaciones Java EE, al generar el Java Servlet aadira dicha variable como
un atributo en la clase Java generada.
Si lo que queremos es definir un mtodo que sume dos nmeros, por ejemplo, lo haramos
as:
<%!
publicintsuma(intparam1,intparam2)
{
returnparam1+param2;
}
%>
El Servidor de Aplicaciones Java EE, al generar el Java Servlet, aadira dicha definicin
como un mtodo en la clase Java generada.
Nota: es muy importante en este punto, tener en cuenta que este tipo de aplicaciones Java
EE son multiusuario y por tanto multitarea. Es decir, se producen n ejecuciones paralelas del
mismo cdigo y por tanto el uso de los atributos o variables de instancia pueden ser
peligrosos y producir efectos no deseados. Asumimos que el lector es conocedor de las
problemticas asociadas a la programacin concurrente tratadas en el Curso de Aula Mentor
Programacin en Java Avanzado. No obstante, volveremos de nuevo a este tema en las
siguientes unidades.

5.3.4 Etiqueta de scriptlets


Los scriptles son las porciones de cdigo Java embebidos en la JavaServer Page.
Utilizan las siguientes etiquetas:
<% %>
Por ejemplo:
<%Stringvar=HolaMundo!;%>
Seguramente, os estaris preguntando si esto no es lo mismo que la etiqueta de declaracin
que vimos antes. La respuesta es no. La declaracin, creaba un atributo, es decir, una
variable de instancia. Sin embargo, en este caso de ahora, al usar un scriptlet, se trata de
una variable local. Pero variable local, de qu mtodo?
Como ya hemos comentado varias veces, el Servidor de Aplicaciones Java EE
automticamente convierte la JavaServer Page en un Java Servlet. Y por tanto, tendr un
mtodo service() como ya vimos en la unidad anterior dedicada a los Java Servlets.
Pues bien, todo el etiquetado de presentacin de la JavaServer Page, as como los
scriptlets, son incluidos en el mtodo service() del Java Servlet autogenerado. Es por tanto
en dicho mtodo donde se crea la variable local de nuestro ltimo ejemplo.
121

Un uso habitual de los scriptlets que dota de gran potencia y dinamismo a las JavaServer
Pages, es su integracin con el etiquetado de presentacin. Por ejemplo:
<%
if(sexo.equals(Hombre))
{
%>
<H1>Buenosdasseor</H1>
<%
}
else
{
%>
<H1>Buenosdasseora</H1>
<%
}
%>
Como podemos observar, hemos conseguido dotar de dinamismo al lenguaje HTML que por
su naturaleza es esttico. Dependiendo del valor de una variable, la etiqueta HTML que se
enva al cliente como parte de la respuesta es una u otra.
Igual que hemos utilizado una bifurcacin, pensad en la flexibilidad que nos da poder usar
tambin un bucle para alimentar listas o tablas de forma dinmica.

5.3.5 Etiqueta de expresin


Este es el ltimo tipo de etiquetas especficas de la tecnologa JavaServer Page.
Este tipo lo que permite es devolver un valor de una variable o un mtodo e insertarlo como
parte de la respuesta.
La sintaxis de la etiqueta es as:
<%= %>
Por ejemplo:
<H1>Elresultadodesumar2+2es:<%=2+2%>.</H1>
O por ejemplo:
Lahoraactuales:<%=Calendar.getInstance().getTime()%>.
Es importante fijarse, que la expresin Java no se termina con el signo de punto y coma (;)
como se hace habitualmente. Evidentemente, no se pueden encadenar expresiones, solo se
permite una.
El Servidor de Aplicaciones Java EE, incluir en el Java Servlet autogenerado el mix de
cdigo esttico y cdigo dinmico como ya aprendimos a hacerlo en la unidad de Java
Servlets.

122

MDULO B Unidad 5: JavaServer Pages

5.3.6 Ejemplo con todas las etiquetas


Vemos un ejemplo completo con todos los tipos de etiquetas en funcionamiento:
<%@pagelanguage="java"contentType="text/html;charset=ISO88591"
pageEncoding="ISO88591"%>
<%@pageimport="java.util.Calendar"%>
<!DOCTYPEhtmlPUBLIC"//W3C//DTDHTML4.01Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<METAhttpequiv="ContentType"content="text/html;charset=ISO
88591">
<TITLE>Calculadora</TITLE>
</HEAD>
<BODY>
<%Mtodoparasumardosnmerosenteros%>
<%!
publicintsumar(intparam1,intparam2)
{
returnparam1+param2;
}
%>
<%
if(request.getParameter("switch")==null)

{
%>
<FORMmethod="POST"action="/EjemplosWeb/calculadora.jsp">
<INPUTtype="hidden"name="switch"value="true">
<TABLEborder="0">
<TR>
<TD>Primernmero:</TD>
<TD><INPUTname="param1"></TD>
</TR>
<TR>
<TD>Segundonmero:</TD>
<TD><INPUTname="param2"></TD>
</TR>
<TR>
<TD><INPUTtype="submit"value="Sumar"></TD>
</TR>
</TABLE>
</FORM>
<%
}
else
{
try
{
intparam1=Integer.parseInt(request.getParameter("param1"));
intparam2=Integer.parseInt(request.getParameter("param2"));
intresult=param1+param2;
%>
Elresultadodelasumaes:<%=sumar(param1,param2)%><BR><BR>
<%
}
catch(NumberFormatExceptionex)
{
%>
123

Algunodelosnmerosnocontenadgitosvlidos...<BR><BR>
<%
}
%>
<%=Calendar.getInstance().getTime()%><BR><BR>
<Ahref="/EjemplosWeb/calculadora.jsp">Volveratrs...</A>
<%
}
%>
</BODY>
</HTML>
Si analizamos detenidamente el ejemplo, podemos observar el uso de los distintos tipos de
etiquetado:
Directivas para definir algunos aspectos tcnicos de la JavaServer Page, as como
aadir imports necesarios para la correcta compilacin.
Comentarios para documentar el objetivo del mtodo sumar.
Declaraciones para definir el mtodo sumar.
Scriptlets para implementar la lgica de control.
Expresiones para devolver los valores calculados.
Evidentemente se trata de un ejemplo, donde hemos intentado utilizar el 100% de los
conceptos expuestos. No quiere decir que la mejor solucin implique utilizarlos todos.
Por cierto, algn lector se habr dado cuenta de la utilizacin de un objeto request sin
haberlo mencionado ni definido en ningn sitio. Las JavaServer Pages cuentan con una serie
de objetos implcitos accesibles desde cualquier punto de la pgina. Los comentaremos en
la siguiente seccin.
Adicionalmente, y simplemente a modo ilustrativo, adjuntamos el cdigo fuente del Java
Servlet que el Servidor de Aplicaciones Java EE habra generado para la JavaServer Page de
ejemplo. Como decimos, es puramente a modo ilustrativo, por si puede ayudar a entender
los conceptos explicados. Recordar que la generacin y compilacin de este Java Servlet es
algo automtico e intrnseco del Servidor de Aplicaciones Java EE:
/*
*GeneratedbytheJaspercomponentofApacheTomcat
*Version:ApacheTomcat/7.0.22
*Generatedat:2012021712:25:10UTC
*Note:Thelastmodifiedtimeofthisfilewassetto
*thelastmodifiedtimeofthesourcefileafter
*generationtoassistwithmodificationtracking.
*/
packageorg.apache.jsp;

importjavax.servlet.*;
importjavax.servlet.http.*;
importjavax.servlet.jsp.*;
importjava.util.Calendar;

124

MDULO B Unidad 5: JavaServer Pages


publicfinalclasscalculadora_jspextends
org.apache.jasper.runtime.HttpJspBase
implementsorg.apache.jasper.runtime.JspSourceDependent{

publicintsumar(intparam1,intparam2)
{
returnparam1+param2;
}

privatestaticfinaljavax.servlet.jsp.JspFactory_jspxFactory=
javax.servlet.jsp.JspFactory.getDefaultFactory();

privatestaticjava.util.Map<java.lang.String,java.lang.Long>
_jspx_dependants;

privatejavax.el.ExpressionFactory_el_expressionfactory;
privateorg.apache.tomcat.InstanceManager_jsp_instancemanager;

publicjava.util.Map<java.lang.String,java.lang.Long>
getDependants(){
return_jspx_dependants;
}

publicvoid_jspInit(){
_el_expressionfactory=
_jspxFactory.getJspApplicationContext(getServletConfig().getServletCon
text()).getExpressionFactory();
_jsp_instancemanager=
org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(ge
tServletConfig());
}

publicvoid_jspDestroy(){
}

publicvoid_jspService(finaljavax.servlet.http.HttpServletRequest
request,finaljavax.servlet.http.HttpServletResponseresponse)
throwsjava.io.IOException,javax.servlet.ServletException{

finaljavax.servlet.jsp.PageContextpageContext;
javax.servlet.http.HttpSessionsession=null;
finaljavax.servlet.ServletContextapplication;
finaljavax.servlet.ServletConfigconfig;
javax.servlet.jsp.JspWriterout=null;
finaljava.lang.Objectpage=this;
javax.servlet.jsp.JspWriter_jspx_out=null;
javax.servlet.jsp.PageContext_jspx_page_context=null;

try{
response.setContentType("text/html;charset=ISO88591");
pageContext=_jspxFactory.getPageContext(this,request,
response,null,true,8192,true);
_jspx_page_context=pageContext;
application=pageContext.getServletContext();
config=pageContext.getServletConfig();
session=pageContext.getSession();
out=pageContext.getOut();
_jspx_out=out;

out.write("\r\n");
out.write("\r\n");
125

out.write("<!DOCTYPEhtmlPUBLIC\"//W3C//DTDHTML4.01
Transitional//EN\"
\"http://www.w3.org/TR/html4/loose.dtd\">\r\n");
out.write("<HTML>\r\n");
out.write("<HEAD>\r\n");
out.write("<METAhttpequiv=\"ContentType\"
content=\"text/html;charset=ISO88591\">\r\n");
out.write("<TITLE>Calculadora</TITLE>\r\n");
out.write("</HEAD>\r\n");
out.write("<BODY>\r\n");
out.write("");
out.write("\r\n");
out.write("");
out.write("\r\n");
out.write("\t");

if(request.getParameter("switch")==null)
{
out.write("\r\n");
out.write("\t<FORMmethod=\"POST\"
action=\"/EjemplosWeb/calculadora.jsp\">\r\n");
out.write("\t\t<INPUTtype=\"hidden\"name=\"switch\"
value=\"true\">\r\n");
out.write("\t\t<TABLEborder=\"0\">\r\n");
out.write("\t\t\t<TR>\r\n");
out.write("\t\t\t\t<TD>Primernmero:</TD>\r\n");
out.write("\t\t\t\t<TD><INPUTname=\"param1\"></TD>\r\n");
out.write("\t\t\t</TR>\r\n");
out.write("\t\t\t<TR>\r\n");
out.write("\t\t\t\t<TD>Segundonmero:</TD>\r\n");
out.write("\t\t\t\t<TD><INPUTname=\"param2\"></TD>\r\n");
out.write("\t\t\t</TR>\r\n");
out.write("\t\t\t<TR>\r\n");
out.write("\t\t\t\t<TD><INPUTtype=\"submit\"
value=\"Sumar\"></TD>\r\n");
out.write("\t\t\t</TR>\r\n");
out.write("\t\t</TABLE>\r\n");
out.write("\t</FORM>\r\n");
out.write("\t");

else

try

intparam1=Integer.parseInt(request.getParameter("param1"));

intparam2=Integer.parseInt(request.getParameter("param2"));
out.write("\r\n");
out.write("\tElresultadodelasumaes:");
out.print(sumar(param1,param2));
out.write("<BR><BR>\r\n");
out.write("\t");

catch(NumberFormatExceptionex)

{
out.write("\r\n");
out.write("\tAlgunodelosnmerosnocontenadgitos
vlidos...<BR><BR>\r\n");
out.write("\t");

}
out.write('\r');
out.write('\n');
126

MDULO B Unidad 5: JavaServer Pages


out.write(' ');
out.print(Calendar.getInstance().getTime());
out.write("<BR><BR>\r\n");
out.write("\t<Ahref=\"/EjemplosWeb/calculadora.jsp\">Volver
atrs...</A>\r\n");
out.write("\t");
}
out.write("\r\n");
out.write("</BODY>\r\n");
out.write("</HTML>");
}catch(java.lang.Throwablet){
if(!(tinstanceofjavax.servlet.jsp.SkipPageException)){
out=_jspx_out;
if(out!=null&&out.getBufferSize()!=0)
try{out.clearBuffer();}catch(java.io.IOExceptione){}
if(_jspx_page_context!=null)
_jspx_page_context.handlePageException(t);
}
}finally{
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
Aunque hay muchas lneas de cdigo que no son fciles de interpretar a estas alturas del
curso, si que de un simple vistazo el alumno debera ser capaz de identificar los mtodos
_jspInit(), _jspService() y _jspDestroy() que son invocados por los mtodos del ciclo de vida
de los Java Servlets estudiados en la unidad anterior. Y si nos centramos en concreto en el
mtodo _jspService(), se debera poder identificar fcilmente la lgica de control de nuestro
JavaServer Page, as como las impresiones del cdigo esttico HTML a la respuesta.
Tambin se puede identificar al inicio, la declaracin del mtodo sumar() como parte del
Java Servlet generado.

5.4

Otros conceptos

En este apartado trataremos algunos otros conceptos relacionados con los JavaServer Pages
que ya hemos mencionado pero no hemos tratado con el suficiente detalle.

5.4.1 El ciclo de vida de un JavaServer Page


Al igual que ocurra con los Java Servlets, los JavaServer Pages tambin siguen un ciclo de
vida definido por el API de la especificacin Java EE. En concreto el interface:
javax.servlet.jsp.HttpJspBase
Dicho ciclo de vida es el mismo que el de los Java Servlets ya que como hemos indicado en
varias ocasiones ya, los JavaServer Pages terminan siendo transformados por el Servidor de
Aplicaciones Java EE en un Java Servlet. La nica diferencia radica en los nombres.
Los mtodos del ciclo de vida de un JavaServer Page son:
127

public void _jspInit();


public _jspService(HttpServletRequest request, HttpServletResponse response);
public void _jspDestroy();
Si quisiramos sobrescribir el comportamiento de inicializacin o finalizacin de un
JavaServer Page, deberamos hacerlo redefiniendo el mtodo en cuestin mediante las
etiquetas de declaracin. Pero es raro tener que hacerlo.
El mtodo _jspService por el contrario, no se sobrescribe nunca, porque ya hemos visto que
cualquier cosa que aadamos al JavaServer Page forma parte de l. Es decir, crear un
JavaServer Page implica siempre sobreescribir el mtodo _jspService.

5.4.2 Objetos implcitos de un JavaServer Page


El contenedor Web de un Servidor de Aplicaciones Java EE, pone a disposicin de los
desarrolladores de JavaServer Pages una serie de objetos implcitos sin necesidad de que
estos tengan que crearlos o buscarlos.
En el ltimo ejemplo que vimos, utilizamos el objeto request que representa a la peticin
HTTP recibida por el JavaServer Page sin necesidad de crearlo, o pedirlo. Directamente
existe y es utilizable.
Los objetos implcitos son:
request: representa la peticin HTTP y normalmente la utilizaremos para acceder a los
parmetros enviados desde el cliente.
response: representa la respuesta HTTP.
session: representa la sesin HTTP del usuario. Este tema lo veremos con mayor
profundidad en siguientes unidades.
application: representa el contexto de la aplicacin. Este tema lo veremos con mayor
profundidad en siguientes unidades.
config: representa la configuracin inicial que se ha hecho para este JavaServer Page.
Este tema lo veremos con mayor profundidad en siguientes unidades.
page: representa la propia pgina. Sera lo mismo que usar la keyword de Java: this.
exception: representa la excepcin que se ha producido y que ha motivado que el
Servidor de Aplicaciones Java EE redirigiese la ejecucin a esta pgina. Debe utilizar la
directiva isErrorPage. Si no se es una pgina definida como pgina de error, este
objeto no estar accesible.
out: representa el writer de escritura de la respuesta HTTP. No suele ser habitual su
uso desde una JavaServer Page..

128

MDULO B Unidad 5: JavaServer Pages


5.4.3 Empaquetado y despliegue
Como comentbamos en la primera unidad de este curso de introduccin al Java EE, una
aplicacin Java EE est formada por un empaquetamiento de una o varias unidades
conocidas con el nombre de mdulos. Este empaquetamiento final era un EAR (Enterprise
ARchive).
Uno de esos mdulos son los Web, que contienen normalmente Java Servlets, JavaServer
Pages (JSP), JavaServer Faces (JSF), contenidos estticos como imgenes, HTMLs, CSSs
Su extensin del fichero empaquetado es WAR (Web ARchive).
En este curso, nos vamos a centrar exclusivamente de este tipo de mdulos, ya que
intentamos cubrir solo la parte web de la programacin Java EE y no el resto de aspectos
que daran lugar a un curso demasiado extenso o a un segundo curso.
A pesar de que las aplicaciones Java EE se empaquetan en un EAR, los Servidores de
Aplicacin que solo cubren parte de la especificacin Java EE como ocurre con Apache
Tomcat, permiten desplegar simplemente mdulos Web aislados. Este ser nuestro caso
durante este curso.
Grficamente, la estructura de un mdulo Web empaquetado sera la siguiente:

Como podemos observar, tiene bastante parecido a la estructura del proyecto web dentro
de Eclipse IDE for Java EE Developers aunque no es igual. En principio, el raz del fichero
WAR correspondera al directorio /WebContent y el directorio /classes del fichero WAR
correspondera al directorio /build/classes.
129

Ahora bien, normalmente no nos preocuparemos mucho de la generacin de un mdulo


Web u otro tipo de mdulo, porque son los IDEs los que nos van a ayudar a generarlo. Por
ejemplo, en nuestro caso, con Eclipse IDE for Java EE Developers basta con seleccionar el
proyecto, pulsar el botn derecho del ratn y seleccionar las opciones Export -> WAR
file:

130

MDULO B Unidad 5: JavaServer Pages


En la siguiente ventana, nos aseguramos que el proyecto seleccionado es el correcto, y
decidimos donde y con que nombre se va a generar el fichero WAR, por ejemplo,
C:\EjemplosWeb.war. Pulsar el botn Finish:

Si vamos a una sesin de DOS, mediante el comando de la JDK jar.exe (jar tvf
nombreFichero.war), podemos ver su contenido y confirmar que la estructura generada es
exactamente la de la especificacin Java EE:

131

Este fichero WAR, sera el que un administrador de Servidores de Aplicacin Java EE


desplegara y configurara para que la aplicacin estuviese disponible y dando servicio. Pero
en nuestro caso, simplemente aadiremos o quitaremos aplicaciones en el Apache Tomcat
de Eclipse IDE for Java EE Developers mediante el interfaz de usuario: botn derecho del
ratn y la opcin Add and Remove, o directamente sobre el componente y Run As ->
Run on Server.
Nos queda no obstante hablar un poco sobre el descriptor de despliegue. Como ya
adelantbamos en la primera unidad, se trata de un fichero XML donde se describe un poco
el contenido y posible comportamiento del contenido del mdulo.
En el caso concreto de los mdulos Web, su descriptor de despliegue es el fichero web.xml
A lo largo de esta unidad, nunca hemos hecho mencin de l, ya que a diferencia de los
Java Servlets, los JavaServer Pages pueden ser invocados directamente mediante el
nombre del fichero sin necesidad de registrarlos en el descriptor de despliegue.
No obstante, es posible registrarlos con otro alias para evitar que sean invocados mediante
el nombre del fichero. Esto se consigue de forma parecida a como hacamos con los Java
Servlets pero con la etiqueta jsp-file en vez de servlet-class.
Veamos un ejemplo:
<?xmlversion="1.0"encoding="UTF8"?>
<webappxmlns:xsi="http://www.w3.org/2001/XMLSchemainstance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/webapp_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/webapp_3_0.xsd"id="WebApp_ID"
version="3.0">
<servlet>
<servletname>CalculadoraJSP</servletname>
<jspfile>/calculadora.jsp</jspfile>
</servlet>
<servletmapping>
<servletname>CalculadoraJSP</servletname>
<urlpattern>/CalculadoraJSP</urlpattern>
</servletmapping>
</webapp>
Si utilizamos este descriptor de despliegue en nuestro ejemplo, en vez de usar esta URL
para invocar nuestra JavaServer Page:
http://localhost:8080/EjemplosWeb/calculadora.jsp
podramos utilizar esta otra:
http://localhost:8080/EjemplosWeb/CalculadoraJSP
Existen muchas mas etiquetas a utilizar en un descriptor de despliegue de un mdulo Web,
pero las iremos viendo a lo largo del curso segn las vayamos necesitando. De momento
nos quedamos con la general web-app y las necesarias para registrar un alias a un
JavaServer Page.
132

MDULO B Unidad 5: JavaServer Pages


Es una buena prctica utilizar siempre el alias y ocultar de esta manera el nombre del fichero
al llamante de la JavaServer Page (JSP).

133

PARA RECORDAR

Los JavaServer Pages, son un tipo de componente Java EE que se empaquen en


un mdulo web (WAR) y se despliegan y ejecutan en el contenedor web de un
Servidor de Aplicaciones Java EE.

Dentro del patrn de diseo MVC ocupan el espacio de la Vista, como encargado
de mostrar el resultado de la peticin al usuario final. Estn enfocadas a la
presentacin.

Un JavaServer Page, es un fichero de extensin *.jsp que utiliza principalmente


lenguajes de etiquetado como el HTML en el que se pueden embeber mediante
unas etiquetas especiales, cdigo Java.

Contienen distintos tipos de etiquetas, como son las:


Comentario: <%-- --%>
Directiva:
o page: aade informacin tcnica a la pgina
o include: se utiliza para incluir el resultado de la ejecucin de otra JSP
o taglib: se utiliza para definir una librera de etiquetas (tags) que se va a utilizar
en la JavaServer Page
Declaracin: <%! %> utilizada para definir atributos y mtodo que sern
accesibles desde toda la JavaServer Page.

Scriptles: <% %> para incluir cdigo Java embebido en la JavaServer Page.

Expresin: <%= %> devuelve el valor de una variable o un mtodo para


insertarlo como parte de la respuesta.

El ciclo de vida de una JavaServer Page es similar a los Java Servlets, solo que
cambian los nombres, jspInit, jspService y jspDestroy

134

Las JavaServer Pages, tienen una serie de objetos a su disposicin de forma


implcita, para utilizarlos en caso de necesitarlos:
request: representa la peticin HTTP
response: representa la respuesta HTTP.
session: representa la sesin HTTP del usuario.
application: representa el contexto de la aplicacin.
config: representa la configuracin inicial que se ha hecho para este JavaServer
Page.
page: representa la propia pgina.
exception: representa la excepcin que se ha
out: representa el writer de escritura de la respuesta HTTP

135

136

Unidad de Aprendizaje 6

DISEO DE APLICACIONES
JAVA EE

NDICE
6.1

Introduccin ................................................................. 139


6.1.1 El Controlador ...............................................................140
6.1.2 La Vista...........................................................................140
6.1.3 El Modelo .......................................................................141

6.2

Conectando Java Servlets con JavaServer Pages . 142


6.2.1 RequestDispatcher .......................................................142
6.2.2 Un ejemplo completo ...................................................143

6.3

Otros patrones de diseo........................................... 147

PARA RECORDAR.................................................................. 150

MDULO B Unidad 6: Diseo de Aplicaciones Java EE

6.1

Introduccin

Llegados a este punto, el alumno ya conoce lo bsico de las tecnologas Java Servlet y
JavaServer Page (JSP), sus pros y contras, puntos fuertes y puntos flojos.
En ms de una ocasin durante las ltimas unidades, hemos comentado que estbamos
haciendo un mal diseo de las aplicaciones pero que desde un punto de vista didctico nos
pareca conveniente hacerlo as, para comprender mejor esta unidad dedicada al diseo de
Aplicaciones Java EE.
Existen multitud de patrones de diseo relacionados con las Aplicaciones Java EE, pero hay
uno ya mencionado durante el curso que tiene en cuenta a la aplicacin en su conjunto y no a
una parte solo.
Estamos hablando del patrn MVC (Modelo-Vista- Controlador o Model-View-Controller en
ingls).
Este patrn de diseo divide la aplicacin en tres roles, cada uno de ellos con unas
responsabilidades muy concretas.

El Modelo (Model): Representa los datos y cualquier lgica de negocio relacionada con
ellos.

La Vista (View): renderiza el contenido de los modelos dependiendo de la tipologa de


cliente (navegador web, telfono mvil, etc).

El Controlador (Controller): define el comportamiento general de la aplicacin


coordinando a las otras dos partes (Modelo y Vista).

Veamos el patrn de diseo en un diagrama:

139

Pues bien, los dos tipos de componentes Java EE que hemos estudiado ya, encajan
perfectamente en este diseo:
Controlador: Java Servlets.
Vista: JavaServer Pages (JSP).

6.1.1 El Controlador
De la experiencia que hemos cogido con las actividades relacionadas con la unidad de los
Java Servlets, hemos visto que son muy potentes para contener cdigo Java, analizar los
parmetros de las peticiones, validarlos, manipularlos, etc pero sin embargo son
realmente tediosos para manejar la presentacin. Para un diseador grfico de pginas
HTML, es realmente complicado crear y mantener dichas pginas a travs de lneas
out.println(.) que dificultan ver el resultado final en su conjunto.

6.1.2 La Vista
Por el contrario, los JavaServer Pages (JSP) han demostrado ser muy valiosos para realizar
el diseo grfico de la presentacin, insertando pequeos scriptlets Java, pero muy tediosos
cuando el nmero de lneas de cdigo Java se incrementa y entonces la mezcla de lgica y
presentacin se hace muy complicada.

140

MDULO B Unidad 6: Diseo de Aplicaciones Java EE


6.1.3 El Modelo
Con lo visto hasta ahora, no parece que ninguna de las dos tecnologas sea la ms
adecuada para implementar la lgica de negocio, es decir, encapsular e implementar la
razn de nuestra Aplicacin Java EE.
Las especificaciones Java EE contemplan un tipo de componente cuyo objetivo es cubrir
este hueco: los Enterprise JavaBeans (EJBs). Pero como no son objetivo de este curso,
utilizaremos directamente POJOs (Plain Old Java Object, o lo que es lo mismo, clases Java
sin ms).

Por tanto, todo en su conjunto quedara visualmente as:

Y el flujo habitual de una aplicacin Java EE a partir de ahora quedar de la siguiente


manera:
1. El cliente, por ejemplo un navegador, solicitar una funcionalidad desde el interface
visual (Vista).
2. Dicha peticin entrar a travs de un Java Servlet (Controlador).
3. Dicho Java Servlet, analizar qu se est pidiendo, qu informacin adicional aporta y
decidir que JavaBean (Modelo) cubre dicha peticin (implementado mediante un
POJO).
4. Lo invocar, y tras recibir un resultado, decidir qu JavaServer Page muestra dicho
resultado al cliente (Vista).
5. El resultado ser devuelto y mostrado.
Para profundizar en el patrn de diseo Model-View-Controller, conectarse al Catlogo OnLine de patrones Java EE:
http://www.oracle.com/technetwork/java/catalog-137601.html

141

6.2

Conectando Java Servlets con JavaServer Pages

Quedan claras entonces las interrelaciones que existirn entre los distintos componentes
estudiados. Pero tcnicamente cmo hacemos dichos enlaces?
La invocacin desde un Java Servlet a un JavaBean (o POJO) es muy sencilla. Simplemente
instanciar la clase en cuestin e invocar algn mtodo de la misma. Pero, y la invocacin
desde un Java Servlet a un JavaServer Page (JSP)?
Dicha invocacin se realiza mediante el interface javax.servlet.RequestDispatcher.

6.2.1 RequestDispatcher
Una instancia del tipo RequestDispatcher, representa la informacin necesaria para lanzar
una peticin a un recurso web. En nuestro caso, podremos lanzar una peticin a otro Java
Servlet o un JavaServer Page (JSP).
El acceso a dicha instancia se puede realizar mediante el mtodo:
RequestDispatcher getRequestDispatcher(java.lang.String path);
de la HttpServletRequest, donde el parmetro que necesita, indica el recurso al que
queremos acceder.
RequestDispatcher tiene dos mtodos:
void forward(ServletRequest request, ServletResponse response) throws.
Este primer mtodo, nos permite redirigir la peticin a otro componente y delegar en l
la respuesta. Es decir, el control de lo que se responde al cliente por parte del Servidor
Java EE queda delegado.
void include(ServletRequest request, ServletResponse response) throws.
Este segundo mtodo nos permite incluir como parte de nuestra respuesta, la
respuesta de otro componente. Es decir, dicho componente colabora con la
respuesta, pero el control lo seguimos teniendo nosotros. Es el mismo resultado que la
directiva JSP include que estudiamos en la unidad anterior.
Los parmetros de ambos mtodos son la peticin y respuesta HTTP. Normalmente sern
los mismos que hemos recibido.
Por tanto, ya sabemos cmo redirigir la ejecucin desde un Java Servlet a un JavaServer
Page (JSP). Pero nos quedara un tema pendiente. Cmo le pasamos informacin de la
lgica de negocio al siguiente?
Existen varias maneras de hacerlo:
A travs de la HttpServletRequest. Podemos utilizar los mtodos setParameter() o
setAttribute() de la peticin para aadir informacin que ser utilizada por el
siguiente componente de la aplicacin mediante los correspondientes mtodos
getParameter() o getAttribute().
A travs de la HttpSession. Todava no hemos estudiado este concepto. Lo trataremos
en la siguiente unidad.
142

MDULO B Unidad 6: Diseo de Aplicaciones Java EE


A travs del ServletContext. Todava no hemos estudiado este concepto. Lo
trataremos en la siguiente unidad.

6.2.2 Un ejemplo completo


Veamos un ejemplo completo de una aplicacin web que resta dos nmeros y que
implementa todos los roles del patrn de diseo Java EE MVC, cada uno de ellos en su sitio
adecuado.
Nota: Aunque un ejemplo tan sencillo se podra pensar en implementar en un solo
componente como hemos hecho en las actividades anteriores, debemos ser capaces de
extrapolar el ejemplo a una aplicacin mucho ms compleja y entenderemos las grandes
ventajas de este diseo que ya utilizaremos siempre a partir de ahora en el curso.

Pgina JSP de cabecera a ser reutilizada (Vista) cabecera.jsp:


<%@pagelanguage="java"contentType="text/html;charset=ISO88591"
pageEncoding="ISO88591"%>
<TABLEborder="0"width="100%">
<TR>
<TDalign="left">
<IMGsrc="/EjemplosWeb/images/banner.gif">
</TD>
<TDalign="center">
<H1>EjemplodeMVC</H1>
</TD>
<TDalign="right">
<IMGsrc="/EjemplosWeb/images/banner.gif">
</TD>
</TR>
</TABLE>
<HR><BR>
Pgina JSP inicial (Vista):
<%@pagelanguage="java"contentType="text/html;charset=ISO88591"
pageEncoding="ISO88591"%>
<!DOCTYPEhtmlPUBLIC"//W3C//DTDHTML4.01Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<METAhttpequiv="ContentType"content="text/html;charset=ISO
88591">
<TITLE>Calculadora</TITLE>
</HEAD>
<BODY>
<%@includefile="/cabecera.jsp"%>

<FORMmethod="POST"action="/EjemplosWeb/RestadorServlet">
<TABLEborder="0">
<TR>
<TD>Primernmero:</TD>
<TD><INPUTname="param1"></TD>
</TR>
143

<TR>
<TD>Segundonmero:</TD>
<TD><INPUTname="param2"></TD>
</TR>
<TR>
<TD><INPUTtype="submit"value="Restar"></TD>
</TR>
</TABLE>
</FORM>
</BODY>
</HTML>
JavaBean o POJO (Modelo) RestadorBean.java:
packagees.aulamentor;

publicclassRestadorBean
{
publicintrestar(intparam1,intparam2)
{
returnparam1+param2;
}
}
Java Servlet (Controlador) index.jsp:
packagees.aulamentor;

importjava.io.IOException;

importjavax.servlet.ServletException;
importjavax.servlet.annotation.WebServlet;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;

@WebServlet(name="RestadorServlet",urlPatterns={"/RestadorServlet"})
publicclassRestadorServletextendsHttpServlet
{

protectedvoiddoGet(HttpServletRequestrequest,
HttpServletResponseresponse)throwsServletException,IOException
{

this.procesarPeticion(request,response);
}

protectedvoiddoPost(HttpServletRequestrequest,
HttpServletResponseresponse)throwsServletException,IOException
{

this.procesarPeticion(request,response);
}

privatevoidprocesarPeticion(HttpServletRequestrequest,
HttpServletResponseresponse)throwsServletException,IOException
{

try

{
intparam1=
Integer.parseInt(request.getParameter("param1"));
144

MDULO B Unidad 6: Diseo de Aplicaciones Java EE

intparam2=
Integer.parseInt(request.getParameter("param2"));

RestadorBeanrestadorBean=newRestadorBean();

intresult=restadorBean.restar(param1,param2);

request.setAttribute("result",result);

request.getRequestDispatcher("/result.jsp").forward(reques
t,response);
}
catch(NumberFormatExceptionex)
{
request.setAttribute("error","Algunodelosnmerosno
contenadgitosvlidos...");

request.getRequestDispatcher("/error.jsp").forward(request
,response);
}
}

Pgina JSP de resultado (Vista) result.jsp:


<%@pagelanguage="java"contentType="text/html;charset=ISO88591"
pageEncoding="ISO88591"%>
<!DOCTYPEhtmlPUBLIC"//W3C//DTDHTML4.01Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<METAhttpequiv="ContentType"content="text/html;charset=ISO
88591">
<TITLE>Calculadora</TITLE>
</HEAD>
<BODY>
<%@includefile="/cabecera.jsp"%>
Elresultadodelasumaes:<%=request.getAttribute("result")%>
<BR><BR>
<Ahref="/EjemplosWeb/index.jsp">Volveratrs...</A>
</BODY>
</HTML>
Pgina JSP de error (Vista) error.jsp:
<%@pagelanguage="java"contentType="text/html;charset=ISO88591"
pageEncoding="ISO88591"%>
<!DOCTYPEhtmlPUBLIC"//W3C//DTDHTML4.01Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<METAhttpequiv="ContentType"content="text/html;charset=ISO
88591">
<TITLE>Calculadora</TITLE>
</HEAD>
<BODY>
<%@includefile="/cabecera.jsp"%>
Sehaproducidoelsiguienteerror:<BR><BR>
<%=request.getAttribute("error")%>
<BR><BR>
145

<Ahref="/EjemplosWeb/index.jsp">Volveratrs...</A>
</BODY>
</HTML>
No es necesario utilizar un descriptor de despliegue, ya que en el Java Servlet hicimos uso
de las Anotaciones Java.
Si el alumno implementa este ejemplo, debera ver algo as
Pgina de inicio:

Pgina de resultado:

146

MDULO B Unidad 6: Diseo de Aplicaciones Java EE


Pgina de error:

6.3

Otros patrones de diseo

A lo largo de la vida de las especificaciones Java EE, se han ido definiendo distintos patrones
de diseo (buenas prcticas) que han demostrado ser muy tiles por distintos motivos tanto en
el desarrollo como en el mantenimiento de las aplicaciones web.
Existe mucha literatura sobre el tema, aunque la gua bsica es la denominada Java EE
BluePrints:
http://java.sun.com/blueprints/patterns/
Este curso no pretende entrar a estudiar en profundidad los distintos patrones, pero si que
comentaremos y utilizaremos alguno adicional que resultan interesantes
A continuacin, listamos alguno sencillo de entender y de mucha utilidad:

Business Delegate (o Delegacin de Negocio): permite reducir el acoplamiento entre la


capa web y la capa de negocio. Se trata de una capa intermedia que abstrae a la capa
de presentacin de la tecnologa empleada en la capa de negocio, es decir,
conseguiramos que la capa de presentacin no supiera si la lgica de negocio se
implementa mediante entidades Java Persistence API (JPA), Enterprise JavaBeans
(EJBs), POJOs, etcy un cambio de tecnologa, no afectara para nada a la capa de
presentacin, solo a los Business Delegates.
Ms informacin en:
http://www.oracle.com/technetwork/java/businessdelegate-142190.html
147

Data Access Object, tambin llamado DAO (u Objeto de Acceso a Datos): permite
abstraer a la lgica de negocio del sistema de persistencia de los datos. Seguramente
a muchos os sonar de cuando estudiasteis el acceso a Bases de Datos con Java:
JDBC (Java DataBase Access). Es decir, la lgica de la aplicacin es agnstica de si
estamos usando Bases de Datos, ficheros, o cualquier otra frmula de persistencia y
acceso a los datos. Nuevamente, un cambio en la forma de hacerlo, solo afectara al
Data Access Object pero no a la lgica de negocio.
Tendremos oportunidad de utilizarlo en los ejemplos y actividades de las siguientes
unidades.
Ms informacin en:
http://www.oracle.com/technetwork/java/dao-138818.html

Front Controller (o Controlador Frontal): se trata de una pieza controladora que


centraliza todas las peticiones y va eligiendo qu lgica de negocio y presentacin son
necesarias para dicha peticin. Sin saberlo, as es como hemos trabajado en esta
unidad. Siempre hemos manejado un nico Java Servlet controlador que ha
gestionado las peticiones.
Evidentemente nuestros ejemplos eran muy sencillos y quizs no se vea la utilidad
pero imaginemos por un momento una aplicacin web tpica de altas, bajas y
modificaciones. Una primera aproximacin podra ser contar con un Java Servlet para
cada peticin, pero este patrn de diseo recomienda tener uno solo que sepa
gestionar de manera centralizada los tres tipos de peticin.
Tendremos oportunidad de utilizarlo en los ejemplos y actividades de las siguientes
unidades.
Ms informacin:
http://www.oracle.com/technetwork/java/frontcontroller-141071.html

Intercepting Filter (o Filtro Interceptor): permite implementar una lgica que se ejecute
siempre previamente a recibir una peticin y posteriormente a enviar la respuesta.
Imaginemos por ejemplo que queremos incluir en nuestra aplicacin un sistema de
logging, o de autenticacin, etc
Tcnicamente se implementa mediante unos Java Servlets especiales denominados
filtros que estudiaremos en la siguiente unidad.
Ms informacin en:
http://www.oracle.com/technetwork/java/interceptingfilter-136585.html

Service Locator (o Localizador de Servicios): permite simplificar el acceso a servicios


de la aplicacin (por ejemplo Enterprise JavaBeans) o del Servidor de Aplicaciones
Java EE (por ejemplo Pool de Conexiones a Bases de Datos o Conectores a Sistemas
Empresariales) encapsulando dicha bsqueda y permitiendo su reutilizacin.

148

MDULO B Unidad 6: Diseo de Aplicaciones Java EE


Hablaremos de nuevo de este patrn en la siguiente unidad, cuando tratemos el
acceso a Bases de Datos y los Pool de Conexiones (conocidos tambin con el nombre
de Data Sources).
Ms informacin en:
http://www.oracle.com/technetwork/java/servicelocator-138528.html

Transfer Object (u Objeto de Transferencia): permite encapsular la informacin que


viaja entre las distintas capas de la aplicacin. Tiene mucho sentido cuando ambas
capas estn separadas fsicamente y por tanto implica una comunicacin por red en
cada peticin. Suele ser mejor desde un punto de vista de rendimiento, pedir una vez y
recibir mucha informacin, que pedir ms de una vez.
Se utiliza frecuentemente en las invocaciones desde la capa de presentacin y la capa
de lgica de negocio cuando esta es distribuida, por ejemplo utilizando Enterprise
JavaBeans (EJBs).
En nuestro caso que utilizamos JavaBeans locales, no tiene un impacto tan grande.
Ms informacin:
http://www.oracle.com/technetwork/java/transferobject-139870.html

149

PARA RECORDAR

En esta unidad hemos visto detalladamente que componentes son los adecuados a
utilizar siguiendo el patrn de diseo MVC:
El Modelo: Representa los datos y cualquier lgica de negocio relacionada con
ellos. Implementado mediante POJOS (tambin EJBs).
La Vista: Renderiza el contenido de los modelos dependiendo de la tipologa de
cliente (navegador web, telfono mvil, etc). Implementado mediante
JavaServer Pages (JSP).
El Controlador: Define el comportamiento general de la aplicacin coordinando
a las otras dos partes (Modelo y Vista). Implementado mediante Java Servlets.

La conexin entre un Java Servlet y un POJO se realiza mediante las llamadas a los
mtodos de dicho componente.

La conexin entre un Java Servlet y un JavaServer Page (JSP) se realiza mediante


los mtodos forward o include (dependiendo de las necesidades) de la clase
RequestDispatcher.

Para pasarle los datos necesarios del Java Servlet y un JavaServer Page (JSP) se
pueden utilizar los siguiente mecanismos:
HttpServletRequest. Podemos
setAttribute() de la peticin

utilizar

los

mtodos

setParameter()

HttpSession.
ServletContext.

Otros patrones de diseo Java EE son:


Business Delegate: permite reducir el acoplamiento entre la capa web y la capa de
negocio.
Data Access Object: permite abstraer a la lgica de negocio del sistema de
150

Front Controller: se trata de una pieza controladora que centraliza todas las
peticiones y va eligiendo qu lgica de negocio y presentacin son necesarias para
dicha peticin.
Intercepting Filter: permite implementar una lgica que se ejecute siempre
previamente a recibir una peticin y posteriormente a enviar la respuesta.
Service Locator: permite simplificar el acceso a servicios de la aplicacin o del
Servidor de Aplicaciones Java encapsulando dicha bsqueda y permitiendo su
reutilizacin.
Transfer Object: permite encapsular la informacin que viaja entre las distintas
capas de la aplicacin

151

152

Unidad de Aprendizaje 7

JAVA SERVLETS AVANZADO

NDICE
7.1

Introduccin ................................................................. 155

7.2

Configuracin de un Java Servlet ............................. 155


7.2.1 Mediante descriptor de despliegue ...........................155
7.2.2 Mediante anotaciones..................................................156

7.3

Concurrencia en un Java Servlet .............................. 158

7.4

Acceso a Bases de Datos........................................... 160


7.4.1 Acceso directo desde el cdigo.................................160
7.4.2 Acceso a travs de un Pool de Conexiones.............166

7.5

Filtros............................................................................. 175

7.6

Mantenimiento del estado del cliente ...................... 179


7.6.1 Cookies ..........................................................................179
7.6.2 Sesin HTTP..................................................................188

7.7

Gestin de eventos...................................................... 193

PARA RECORDAR.................................................................. 201

MDULO C Unidad 7: Java Servlets Avanzado

7.1

Introduccin

A estas alturas del curso, ya hemos aprendido las tecnologas bsicas sobre las que se apoya
el desarrollo de aplicaciones web Java EE y cundo usar unas u otras. Incluso ya hemos
desarrollado algunas aplicaciones sencillas.
El objetivo de las siguientes unidades, es profundizar en estas tecnologas para poderle sacar
ms provecho y llegar a desarrollar aplicaciones Java EE reales.

7.2

Configuracin de un Java Servlet

Como bien recordars de las unidades anteriores, el ciclo de vida de un Java Servlet tena un
mtodo de inicializacin:
public void init(ServletConfig config);
que se ejecutaba una sola vez al inicio de la vida del Java Servlet y que se sola utilizar para
llevar a cabo todas las labores de inicializacin y configuracin que necesitramos para su
posterior ejecucin.
Como

se

puede

observar,

javax.servlet.ServletConfig,

que

recibe

como

representa

parmetro
la

una

informacin

de

instancia

de

configuracin

la

clase

que

el

administrador del Servidor de Aplicaciones Java EE haya podido aadir.


Dicha clase tiene distintos mtodos para facilitar el acceso a su informacin:

java.lang.String getInitParameter(java.lang.String name)


Devuelve el parmetro de configuracin que coincide con el nombre que se enva.

java.util.Enumeration<java.lang.String> getInitParameterNames()
Devuelve una coleccin con los nombres de todos los parmetros de configuracin
que tiene.

Y cmo aadimos informacin de configuracin a un Java Servlet? Pues bien, el


desarrollador tiene dos modos de aadir dicha informacin:

Mediante el descriptor de despliegue.

Mediante anotaciones en el cdigo (a partir de Java EE 6.0).

7.2.1 Mediante descriptor de despliegue


Consiste en aadir un bloque init-param por cada parmetro, con parejas de bloques
param-name y param-value, dentro del bloque servlet que ya conocemos y hemos
utilizado anteriormente.
Veamos un ejemplo de un Java Servlet que recibe dos parmetros de configuracin
mediante el descriptor de despliegue:
155

<?xmlversion="1.0"encoding="UTF8"?>
<webappxmlns:xsi="http://www.w3.org/2001/XMLSchemainstance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/webapp_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/webapp_3_0.xsd"id="WebApp_ID"
version="3.0">
<servlet>
<servletname>ConfigServlet</servletname>
<servletclass>es.aulamentor.ConfigServlet</servletclass>
<initparam>
<paramname>param1</paramname>
<paramvalue>Hola</paramvalue>
</initparam>
<initparam>
<paramname>param2</paramname>
<paramvalue>Mundo</paramvalue>
</initparam>
</servlet>
<servletmapping>
<servletname>ConfigServlet</servletname>
<urlpattern>/ConfigServlet</urlpattern>
</servletmapping>
</webapp>

7.2.2 Mediante anotaciones


Se realiza aadiendo el atributo initParams a la anotacin @WebServlet que ya hemos
utilizado anteriormente. Dicho atributo, contiene a su vez, anotaciones @WebInitParam por
cada parmetro, la cual nuevamente, contiene parejas de atributos name y value.
Se entiende mucho ms fcil con un ejemplo:
packagees.aulamentor;

importjava.io.IOException;
importjava.util.Enumeration;

importjavax.servlet.ServletConfig;
importjavax.servlet.ServletException;
importjavax.servlet.annotation.WebInitParam;
importjavax.servlet.annotation.WebServlet;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;

@WebServlet(name="ConfigServlet",urlPatterns={"/ConfigServlet"},
initParams={@WebInitParam(name="param1",value="Hola"),
@WebInitParam(name="param2",value="Mundo")})
publicclassConfigServletextendsHttpServlet
{
publicvoidinit(ServletConfigconfig)throwsServletException
{
Enumeration<String>parameters=config.getInitParameterNames();
while(parameters.hasMoreElements())
{
Stringname=parameters.nextElement();
156

MDULO C Unidad 7: Java Servlets Avanzado


System.out.println("Nombre:"+name+"Valor:"+
config.getInitParameter(name));
}
}

protectedvoiddoGet(HttpServletRequestrequest,
HttpServletResponseresponse)throwsServletException,
IOException
{
}
}
Este cdigo de ejemplo en ejecucin dentro del entorno de desarrollo mostrara algo as:

Ambos dos mtodos no son excluyentes, aunque no tiene mucho sentido utilizar ambos para
un mismo Java Servlet. No obstante, si as fuera y en el hipottico caso de que en ambos dos
sitios existiera un parmetro con el mismo nombre, tendra prioridad el del descriptor de
despliegue.

157

7.3

Concurrencia en un Java Servlet

Nota: En esta seccin se asume que el alumno tiene conceptos de programacin avanzada en
Java, en concreto, en la programacin concurrente con Java Threads.
Se dice que una aplicacin soporta concurrencia cuando permite ejecuciones en paralelo de
su cdigo. Es decir, en el caso de las aplicaciones Java EE que estamos estudiando,
significara que varios usuarios puedan conectarse y ejecutar la aplicacin a la vez.
Las aplicaciones Java EE son concurrentes por naturaleza. El Servidor de Aplicaciones Java
EE se encarga de controlar y permitir la concurrencia de la aplicacin permitiendo al
desarrollador prcticamente despreocuparse de esta casustica.
Teniendo en cuenta que solamente hay una instancia de un Java Servlet por cada JVM, no
debemos olvidarnos nunca del tema y tenerlo siempre presente en nuestros desarrollos para
evitar problemas y comportamientos no deseados. Por ejemplo, imaginemos lo que puede
ocurrir si utilizamos variables de instancia en el Java Servlet para manejar una informacin
temporal durante la ejecucin de un mtodo, en el que hemos sustituido un posible cdigo
que tarda cierto tiempo en ejecutar por un Thread.sleep(5000);
packagees.aulamentor;

importjava.io.IOException;
importjavax.servlet.ServletException;
importjavax.servlet.annotation.WebServlet;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;

@WebServlet("/ConcurrenciaServlet")
publicclassConcurrenciaServletextendsHttpServlet
{
privateintval=0;

protectedvoiddoGet(HttpServletRequestrequest,HttpServletResponse
response)throwsServletException,IOException
{
val=Integer.parseInt(request.getParameter("param"));
System.out.println("Thread:"+Thread.currentThread().getName()+
"usaelvalor:"+val);
try
{
//Simulamosqueelservletestconalgunaoperativaantesde
//volverautilizarelvalordelavariableval.
Thread.sleep(5000);
}
catch(InterruptedExceptionex)
{
}
System.out.println("Thread:"+Thread.currentThread().getName()+
"usaelvalor:"+val);
}
}
E invocamos desde el navegador a este Java Servlet dos veces consecutivas (en menos de 5
segundos) primero con el parmetro 5 y luego con el parmetro 2:
158

MDULO C Unidad 7: Java Servlets Avanzado


http://localhost:8080/EjemplosWeb/ConcurrenciaServlet?param=5
http://localhost:8080/EjemplosWeb/ConcurrenciaServlet?param=2
Observemos en la salida por consola lo que ocurre:

La primera peticin la sirve un thread controlado por el Servidor de Aplicaciones Java EE que
se llama http-bio-8080-exec3 y el inicio de la ejecucin del Java Servlet muestra que el
parmetro con el que tiene que trabajar vale 5. Entonces, se duerme durante 5 segundos (ha
sido la forma de simular una tarea costosa) y cuando vuelve a por el parmetro, resulta que
vale 2.
Qu ha pasado? Lo que ha pasado es que antes de que el primer Java Servlet terminara de
ejecutarse, el Servidor de Aplicaciones Java EE recibi una segunda peticin al mismo Java
Servlet con un valor del parmetro distinto. Como ambos dos threads, en este caso http-bio8080-exec-4, ejecutan el mismo cdigo, el segundo ha machacado el valor al primero.
Se trata de un ejemplo muy sencillo, pero el problema que demuestra puede ser muy
complicado de detectar.
Existen distintas soluciones:
159

Evitar en la medida de lo posible utilizar variables de instancia cuando su valor es de


escritura/lectura.

Implementar el interface javax.servlet.SingleThreadModel que le indica al Servidor de


Aplicaciones Java EE, que no puede paralelizar las ejecuciones de este Java Servlet.
Esta solucin no es recomendable porque por regla general implica un tiempo de
respuesta psimo a los usuarios. Imaginad cien usuarios pidiendo este servicio a la
vez y teniendo que esperar en cola a ser respondidos.

7.4

Utilizar tcnicas de sincronizacin del lenguaje Java (synchronized).

Acceso a Bases de Datos

Nota: En esta seccin se asume que el alumno tiene conceptos de programacin avanzada en
Java, en concreto, en la programacin de acceso a Bases de Datos con JDBC.
Existen distintas alternativas para el acceso a Bases de Datos desde aplicaciones web. Vamos
a comentar dos de ellas: mediante el acceso directo a la Base de Datos desde el cdigo y
mediante un servicio que nos proveen los Servidores de Aplicaciones Java EE denominado
Pool de Conexiones (o Data Source).
La primera alternativa tiene bastantes problemas (uno de ellos es que tiene peor rendimiento
que las otras alternativas) y no es para nada recomendada. Pero, no obstante, la veremos
brevemente para entender mejor la naturaleza de una aplicacin web, el por qu esta es una
mala alternativa y cmo la segunda es una opcin mucho mejor.

7.4.1 Acceso directo desde el cdigo


Este mtodo supone ejecutar todos los pasos tpicos del API JDBC en el cdigo de nuestra
aplicacin:
Cargar el Driver JDBC en la JVM.
Crear una conexin a la Base de Datos.
Crear una sentencia (de cualquiera de los tipos) y ejecutarla.
Analizar el resultado de la sentencia.
Cerrar y liberar los recursos.
Con lo que conocemos ya del desarrollo de Java Servlets, podramos pensar en colocar los
distintos pasos en distintos lugares del cdigo.
Por ejemplo, una opcin sera realizar la carga del Driver JDBC, la creacin de la conexin a
la Base de Datos y de la sentencia a ejecutar en el mtodo de inicializacin de Java Servlet
(init). En los mtodos de proceso de HTTP GET o HTTP POST (doGet o doPost) la ejecucin

160

MDULO C Unidad 7: Java Servlets Avanzado


de la sentencia y anlisis del resultado. Y por ltimo, en el mtodo de finalizacin del Java
Servlet (destroy) incluiramos el cdigo de limpieza, cerrando y liberando los recursos.
Ahora bien, esta opcin tiene un inconveniente, y es que la sentencia ser una variable de
instancia (o atributo), y como ya hemos tratado en la seccin anterior, debido a que las
aplicaciones web son multiusuario (multithread) por naturaleza, tendramos que tener en
cuenta el acceso sincronizado a la variable.
Podramos pensar entonces en otra opcin, y sera pasar todos los pasos a los mtodos de
proceso de HTTP GET y HTTP POST (doGet y doPost) dejando nicamente la carga del
Driver JDBC en el mtodo de inicializacin (init). En este caso es cierto que no tendremos
que estar pendientes de sincronizar el acceso a ninguna variable de instancia (o atributo),
pero penalizamos enormemente el rendimiento (tiempo de respuesta) de la aplicacin al
estar conectando y desconectando constantemente con la Base de Datos.
Vamos a ver un ejemplo de cdigo para que se visualice mejor esta primera alternativa de
acceso a Bases de Datos aunque como ya dijimos no es la recomendada.
El ejemplo consiste en una aplicacin web de consulta de ttulos de libros mediante el
cdigo ISBN:
Pgina HTML de inicio:
<!DOCTYPEhtmlPUBLIC"//W3C//DTDHTML4.01Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<METAhttpequiv="ContentType"content="text/html;charset=ISO
88591">
<TITLE>AccesoaBasesdeDatos</TITLE>
</HEAD>
<BODY>
<FORMmethod="POST"action="/EjemplosWeb/BaseDatosServlet">
<TABLEborder="0">
<TR>
<TD>IntroduzcaelISBN:</TD>
<TD><INPUTname="isbn"></TD>
</TR>
<TR>
<TD><INPUTtype="submit"value="Buscar"></TD>
</TR>
</TABLE>
</FORM>
</BODY>
</HTML>
Java Servlet con la lgica:
packagees.aulamentor;

importjava.io.IOException;
importjava.sql.Connection;
importjava.sql.DriverManager;
importjava.sql.PreparedStatement;
importjava.sql.ResultSet;
161

importjava.sql.SQLException;

importjavax.servlet.ServletConfig;
importjavax.servlet.ServletException;
importjavax.servlet.annotation.WebServlet;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;

@WebServlet("/BaseDatosServlet")
publicclassBaseDatosServletextendsHttpServlet
{
publicvoidinit(ServletConfigconfig)throwsServletException
{
try
{
Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
}
catch(ClassNotFoundExceptionex)
{
System.out.println("DriverJDBCnoencontrado...");
ex.printStackTrace();
}
}

protectedvoiddoPost(HttpServletRequestrequest,
HttpServletResponseresponse)throwsServletException,IOException
{
Connectioncon=null;
PreparedStatementpstmt=null;
ResultSetrs=null;
Stringisbn=request.getParameter("isbn");

try
{
con=DriverManager.getConnection("jdbc:derby:D:/biblioteca",
"derbyuser","derbyuser");
pstmt=con.prepareStatement("SELECT*FROMPRESTAMOSWHEREISBN
=?");
pstmt.setString(1,isbn);
rs=pstmt.executeQuery();
if(rs.next())
{

request.setAttribute("titulo",rs.getString(3));
}
request.getRequestDispatcher("/resultDB.jsp").forward(request,
response);
}
catch(SQLExceptionex)
{
System.out.println("ProblemasenelaccesoalaBD...");
ex.printStackTrace();
}
finally
{
try
{
if(rs!=null)
rs.close();
}
catch(SQLExceptionex)
162

MDULO C Unidad 7: Java Servlets Avanzado


{
ex.printStackTrace();
}
try
{
if(pstmt!=null)
pstmt.close();
}
catch(SQLExceptionex)
{
ex.printStackTrace();
}
try
{
if(con!=null)
con.close();
}
catch(SQLExceptionex)
{
ex.printStackTrace();
}
}
}
}
Pgina JSP de resultado:
<%@pagelanguage="java"contentType="text/html;charset=ISO88591"
pageEncoding="ISO88591"%>
<!DOCTYPEhtmlPUBLIC"//W3C//DTDHTML4.01Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<METAhttpequiv="ContentType"content="text/html;charset=ISO
88591">
<TITLE>AccesoaBasesdeDatos</TITLE>
</HEAD>
<BODY>
<%
if(request.getAttribute("titulo")!=null)
{
%>
Elttulodellibroes:<%=request.getAttribute("titulo")%>
<%
}
else
{
%>
CdigoISBNnoencontrado.
<%
}
%>
<BR><BR>
<Ahref="/EjemplosWeb/indexDB.html">Volveratrs...</A>
</BODY>
</HTML>

163

En esta ocasin, nuestra aplicacin est haciendo uso de los Drivers JDBC de una Base de
Datos (en concreto de Apache Derby) por lo que tendremos que tener en cuenta aadir el
fichero JAR que contiene dichas clases Java en nuestra aplicacin.
La estructura de un mdulo Web segn las especificaciones Java EE dictaba que este tipo
de ficheros deban ubicarse en el directorio /WEB-INF/lib, que en un proyecto web de
Eclipse IDE for Java EE Developers corresponde a /WebContent/WEB-INF/lib:

Otra opcin sera aadir el fichero a la instalacin del Servidor de Aplicaciones Java EE en
vez de aadirlo a cada mdulo web que acceda a la Base de Datos.
La configuracin de esta opcin es dependiente del servidor, es decir, dependiendo del
servidor que estemos utilizando se har de una manera u otra. En nuestro caso, que
estamos utilizando Apache Tomcat 7.0.x, el fichero JAR se debe copiar en el directorio /lib
de la instalacin:

164

MDULO C Unidad 7: Java Servlets Avanzado

Independientemente de la opcin de configuracin elegida, la ejecucin del ejemplo debera


mostrar algo as
Pgina de inicio:

Pgina de resultado:

165

No obstante, como ya hemos comentado, esta forma de acceder a Bases de Datos tiene
graves problemas de rendimiento en el caso de tener muchos usuarios y adems, si
decidimos compartir la conexin y la sentencia a travs de una variable de instancia (o
atributo) para mejorar algo el rendimiento, tenemos que introducir en la programacin
tcnicas de sincronizacin que no son triviales.
Por este motivo, las especificaciones Java EE definieron el concepto de Pool de Conexiones
(Data Source) que todo Servidor de Aplicaciones Java EE debe implementar y que
estudiaremos a continuacin.

7.4.2 Acceso a travs de un Pool de Conexiones


Todo Servidor de Aplicaciones Java EE, debe implementar un servicio de Pool de
Conexiones a Bases de Datos que implemente el siguiente interface:
javax.sql.DataSource
Dicho interface tiene solo dos mtodos que permiten el acceso a una conexin:
Connection getConnection() throws SQLException;
Devuelve una conexin a Base de Datos disponible del pool.
Connection getConnection(String username, String password) throws SQLException;
Devuelve una conexin a Base de Datos disponible del pool pero usando un usuario y
contrasea especfico (no necesariamente el que use por defecto el Data Source).
Al tratarse de un servicio del Servidor de Aplicaciones Java EE, tendremos que crearlo y
configurarlo en el servidor para que sea accesible desde nuestra aplicacin web. Y
evidentemente, esto no se hace en el cdigo sino en el propio servidor.
Cada Servidor de Aplicaciones Java EE tiene su propio mecanismo de administracin, es
decir, las especificaciones Java EE dictan qu servicios e interfaces deben implementar,
166

MDULO C Unidad 7: Java Servlets Avanzado


pero indican en cmo lo tienen que hacer. Por tanto, la forma de configurar el servidor
depender del que estemos usando.
A continuacin, comentaremos cmo se configura un Pool de Conexiones en Apache
Tomcat 7.0.x que es el Servidor de Aplicaciones Java EE que estamos utilizando a lo largo
de este curso.
Apache Tomcat 7.0.x basa toda su administracin y configuracin en ficheros XML que
residen en el directorio /conf. Pero como en nuestro caso lo estamos usando integrado en
Eclipse IDE for Java EE Developers, existe un proyecto especial adicional a los dedicados a
nuestros desarrollos que se llama Servers. Ah es donde residen los ficheros XML de
configuracin del Apache Tomcat 7.0.x que estamos utilizando.

En concreto, para configurar un Pool de Conexiones nuevo, debemos editar el fichero de


configuracin context.xml, y a la seccin ya existente <Context> </Context> aadirle el
siguiente bloque Resource:
<Resource

name="jdbc/TestDB"

auth="Container"

type="javax.sql.DataSource"

maxActive="100"

maxIdle="30"

maxWait="10000"
username="derbyuser"
password="derbyuser"
167

driverClassName="org.apache.derby.jdbc.EmbeddedDriver"
url="jdbc:derby:D:/biblioteca"/>

Este bloque Resource define y configura un Pool de Conexiones a la Base de Datos


Apache Derby que estamos usando en nuestro ejemplo.
Repasemos el significado de algunas de las propiedades de la configuracin:
name: identificador JNDI (Java Naming and Directory Interface) que utilizaremos para
acceder al pool.
type:

tipo

de

interface

que

implementa

el

recurso

(en

nuestro

caso

javax.sql.DataSource).
username: identificador de usuario en el caso de que el Gestor de Base de Datos que
estamos utilizando tenga la seguridad activada.
password: contrasea de usuario en el caso de que el Gestor de Base de Datos que
estamos utilizando tenga la seguridad activada.
driverClassName: nombre del Driver JDBC de acceso al Gestor de Base de Datos
que estamos utilizando.
url: URL JDBC.
El resto de propiedades suelen estar relacionadas con las caractersticas ms funcionales
del Pool de Conexiones, temas como el nmero mximo de conexiones que puede tener, el
tiempo mximo que una conexin puede estar asignada sin ser devuelta al pool, etc
Con esto, el Servidor de Aplicaciones Java EE ya va a crear y gestionar un Pool de
Conexiones con nuestra Base de Datos. Ahora, nos queda indicar que nuestra aplicacin
web est interesada en el acceso a dicho pool y lo haremos mediante el descriptor de
despliegue del mdulo web (web.xml).
Para ello, aadiremos el siguiente bloque resource-ref:
<resourceref>
<description>ConexionBD</description>
<resrefname>jdbc/TestDB</resrefname>
<restype>javax.sql.DataSource</restype>
<resauth>Container</resauth>
</resourceref>
Simplemente hacemos referencia al recurso creado y configurado en el servidor,
identificando bsicamente el nombre (res-ref-name) y tipo (res-type). De esta manera, al
desplegar la aplicacin web, el Servidor de Aplicaciones Java EE nos dar acceso al
recurso.
Ya solo nos queda modificar el cdigo fuente de nuestra aplicacin para que ahora haga uso
del Data Source en vez de crear las conexiones a la Base de Datos directamente.

168

MDULO C Unidad 7: Java Servlets Avanzado


Para buscar y acceder a un recurso definido en el Servidor de Aplicaciones Java EE se utiliza
el API JNDI (Java Naming and Directory Interface). Es el API a travs del cual podemos
conectarnos al directorio de recursos del servidor y acceder a ellos. Dicho API se encuentra
en el paquete Java: javax.naming;
Su uso es muy sencillo y normalmente consta de dos pasos:
Creacin del Contexto de bsqueda: direccin IP, puerto del servicio, y punto de
entrada en el directorio.
Realizacin de la bsqueda del recurso y downcasting a su tipo concreto.
Veamos un ejemplo tpico:
try
{
ContextinitialContext=newInitialContext();
DataSourcedatasource=
(DataSource)initialContext.lookup("java:comp/env/jdbc/TestDB");
}
catch(NamingExceptionex)
{
System.out.println("Problemasenelaccesoalrecurso...");
ex.printStackTrace();
}
En el ejemplo creamos un Contexto con los valores por defecto, es decir, acceso al servicio
del propio Servidor de Aplicaciones Java EE en el que la aplicacin se est ejecutando
desde la raz del directorio. Si hubiramos querido conectar con un servicio JNDI de otro
Servidor de Aplicaciones Java EE remoto, tendramos que haber creado el Contexto con los
parmetros adecuados.
Y a continuacin, realizamos la bsqueda del recurso con el nombre jdbc/TestDB, que nos
es devuelto como un java.lang.Object y de ah que debamos hacer el downcasting a
javax.sql.DataSource.
Si no se encontrase el recurso por el motivo que fuese (el nombre est mal, no est bien
configurado

en

el

servidor,

etc)

se

producir

una

excepcin

javax.naming.NamingException que deberemos tratar segn la lgica de nuestra aplicacin.


El lugar dentro del servicio JNDI donde se ubican siempre todos los recursos accesibles a
las aplicaciones web es: java:comp/env, de ah que la bsqueda no haya sido solo de
jdbc/TestDB sino que ha sido de java:comp/env/jdbc/TestDB.
Por ltimo, ya solo quedara pedirle al Data Source una conexin disponible a la Base de
Datos a travs de uno de los mtodos comentados al inicio de este apartado. En este punto
se encuentra la clave de esta alternativa de programacin de acceso a Bases de Datos. En
este caso, al contrario que ocurra cuando la conexin se la pedamos al DriverManager, la
conexin ya est establecida con el Gestor de Base de Datos con lo que el tiempo de
respuesta es mucho mayor. Adems, varias ejecuciones paralelas de nuestra aplicacin
169

pueden estar accediendo a la Base de Datos en paralelo, no como antes que el acceso era
sincronizado (y por tanto serializado) a una nica conexin.
No obstante, al igual que cuando accedamos directamente a la Base de Datos desde el
cdigo, es importante liberar los recursos cuando se han dejado de utilizar. En este caso, la
diferencia es que la llamada al mtodo close de la conexin, en vez de cerrarla lo que hace
es devolverla al Pool de Conexiones como disponible para poder ser utilizada por otra
peticin.
Veamos la aplicacin de ejemplo de antes, pero esta vez utilizando un Pool de Conexiones.
Descriptor de despliegue:
<?xmlversion="1.0"encoding="UTF8"?>
<webappxmlns:xsi="http://www.w3.org/2001/XMLSchemainstance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/webapp_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/webapp_3_0.xsd"id="WebApp_ID"
version="3.0">
<servlet>
<servletname>DataSourceServlet</servletname>
<servletclass>es.aulamentor.DataSourceServlet</servletclass>
</servlet>
<servletmapping>
<servletname>DataSourceServlet</servletname>
<urlpattern>/DataSourceServlet</urlpattern>
</servletmapping>
<resourceref>
<description>ConexionBD</description>
<resrefname>jdbc/TestDB</resrefname>
<restype>javax.sql.DataSource</restype>
<resauth>Container</resauth>
</resourceref>
</webapp>
Pgina HTML de inicio:
<!DOCTYPEhtmlPUBLIC"//W3C//DTDHTML4.01Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<METAhttpequiv="ContentType"content="text/html;charset=ISO
88591">
<TITLE>AccesoaBasesdeDatos</TITLE>
</HEAD>
<BODY>
<FORMmethod="POST"action="/EjemplosWeb/DataSourceServlet">

<TABLEborder="0">

<TR>

<TD>IntroduzcaelISBN:</TD>

<TD><INPUTname="isbn"></TD>

</TR>

<TR>

<TD><INPUTtype="submit"value="Buscar"></TD>

</TR>

</TABLE>
</FORM>
170

MDULO C Unidad 7: Java Servlets Avanzado


</BODY>
</HTML>
Java Servlet:
packagees.aulamentor;

importjava.io.IOException;
importjava.sql.Connection;
importjava.sql.PreparedStatement;
importjava.sql.ResultSet;
importjava.sql.SQLException;

importjavax.naming.Context;
importjavax.naming.InitialContext;
importjavax.naming.NamingException;
importjavax.servlet.ServletConfig;
importjavax.servlet.ServletException;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importjavax.sql.DataSource;

publicclassDataSourceServletextendsHttpServlet
{
DataSourcedatasource=null;

publicvoidinit(ServletConfigconfig)throwsServletException
{
try
{
ContextinitialContext=newInitialContext();
datasource=
(DataSource)initialContext.lookup("java:comp/env/jdbc/TestDB");
}
catch(NamingExceptionex)
{
System.out.println("ProblemasenelaccesoalaBasede
Datos...");
ex.printStackTrace();
}
}

protectedvoiddoPost(HttpServletRequestrequest,
HttpServletResponseresponse)throwsServletException,IOException
{
Connectioncon=null;
PreparedStatementpstmt=null;
ResultSetrs=null;
Stringisbn=request.getParameter("isbn");

try
{
con=datasource.getConnection();
pstmt=con.prepareStatement("SELECT*FROMPRESTAMOSWHEREISBN
=?");
pstmt.setString(1,isbn);
rs=pstmt.executeQuery();
if(rs.next())
{
request.setAttribute("titulo",rs.getString(3));
171

}
request.getRequestDispatcher("/resultDS.jsp").forward(request,
response);
}
catch(SQLExceptionex)
{
System.out.println("ProblemasenelaccesoalaBasede
Datos...");
ex.printStackTrace();
}
finally
{
try
{
if(rs!=null)
rs.close();
}
catch(SQLExceptionex)
{
ex.printStackTrace();
}
try
{
if(pstmt!=null)
pstmt.close();
}
catch(SQLExceptionex)
{
ex.printStackTrace();
}
try
{
if(con!=null)
con.close();
}
catch(SQLExceptionex)
{
ex.printStackTrace();
}
}
}
}
Pgina JSP de resultado:
<%@pagelanguage="java"contentType="text/html;charset=ISO88591"
pageEncoding="ISO88591"%>
<!DOCTYPEhtmlPUBLIC"//W3C//DTDHTML4.01Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<METAhttpequiv="ContentType"content="text/html;charset=ISO
88591">
<TITLE>AccesoaBasesdeDatos</TITLE>
</HEAD>
<BODY>
<%
if(request.getAttribute("titulo")!=null)
{
%>
Elttulodellibroes:<%=request.getAttribute("titulo")%>
172

MDULO C Unidad 7: Java Servlets Avanzado


<%
}
else
{
%>
CdigoISBNnoencontrado.
<%
}
%>
<BR><BR>
<Ahref="/EjemplosWeb/indexDS.html">Volveratrs...</A>
</BODY>
</HTML>
La ejecucin del ejemplo debera mostrar exactamente los mismos resultados que antes. Es
decir, el cmo accedamos a la Base de Datos no afecta en nada a la presentacin de la
aplicacin aunque seguramente si se notar mejor rendimiento (la bsqueda se har ms
rpida).
Pgina de inicio:

Pgina de resultado:

173

Ahora bien, como ya hemos comentado en otras ocasiones, a partir de Java EE 6.0 existe
otra alternativa al descriptor de despliegue y cdigo Java. Son las anotaciones Java.
Veamos cmo quedara el mismo ejemplo usando la anotacin @Resource. En vez de
escribir las lneas de cdigo necesarias para realizar la bsqueda:
publicclassDataSourceServletextendsHttpServlet
{
DataSourcedatasource=null;

publicvoidinit(ServletConfigconfig)throwsServletException
{
try
{
ContextinitialContext=newInitialContext();
datasource=
(DataSource)initialContext.lookup("java:comp/env/jdbc/TestDB");
}
catch(NamingExceptionex)
{
System.out.println("ProblemasenelaccesoalaBD...");
ex.printStackTrace();
}
}
podramos simplemente usar esta anotacin:
publicclassDataSourceServletextendsHttpServlet
{
@Resource(name="java:comp/env/jdbc/TestDB")
DataSourcedatasource;
teniendo en cuenta importar el paquete: javax.annotation;
Cualquiera de las dos opciones es vlida.
Adicionalmente, existe otra anotacin muy til sobre todo para los entornos de desarrollo
locales que permite realizar la definicin de los DataSources sin necesidad de tocar los
ficheros de configuracin de los Servidores de Aplicacin Java EE. Es mediante la anotacin
@DataSourceDefinition que requiere importar el paquete: javax.annotation.sql;
Nota: esta opcin no est disponible en el servidor Apache Tomcat 7.0.x que utilizamos en
este curso (que como recordaremos, no implementaba el 100% de las especificaciones Java
EE, sola las relacionadas con la capa web), pero no obstante la comentamos:
@DataSourceDefinition(name="java:comp/env/jdbc/TestDB",className=
"org.apache.derby.jdbc.EmbeddedDriver",url=
"jdbc:derby:D:/biblioteca")
publicclassDataSourceServletextendsHttpServlet
{
@Resource(name="java:comp/env/jdbc/TestDB")
DataSourcedatasource;

174

MDULO C Unidad 7: Java Servlets Avanzado


En este ultimo ejemplo, vemos como en el propio cdigo realizamos la definicin del
DataSource. Los Servidores de Aplicacin Java EE, al encontrar este cdigo, dinmicamente
crean el DataSource sin necesidad de haberlo definido en la configuracin del servidor.
Esta manera de definirlos est recomendada nicamente en los entornos locales de los
desarrolladores, para facilitar y agilizar las pruebas. Pero no es la manera recomendada de
configurarlos en los entornos reales de ejecucin donde debern ser los administradores los
que decidan cmo configurarlos.
El uso de Pool de Conexiones, siempre lleva relacionado temas de tunning (ajustes de la
configuracin para mejorar el rendimiento), pero este es un tema que trasciende el mbito de
este curso y que adems es muy dependiente del Servidor de Aplicaciones Java EE que se
est utilizando. Pero si es interesante que recuerdes que es importante que los
administradores del servidor realicen pruebas de carga y analicen cmo afecta al
rendimiento de la aplicacin el nmero mximo de conexiones disponible en el pool entre
otros parmetros, decidiendo el valor ptimo en cada caso.

7.5

Filtros

Un filtro es un componente web ms, que a diferencia de los que hemos visto hasta ahora no
son invocados directamente. Son unos componentes que se despliegan como parte de la
aplicacin Web, y cuya misin es interceptar las peticiones y respuesta de un componente
concreto para por ejemplo, realizar algn tipo de validacin, algn tipo de auditoria, algn tipo
de transformacin, etc
Es decir, sin que el usuario lo sepa, antes y despus de la ejecucin de un componente web
se ejecuta este nuevo componente.
Un filtro de implementar el interface: javax.servlet.Filter que incluye tres mtodos:

void init(FilterConfig filterConfig) throws ServletException;

Se invoca una nica vez en la vida del filtro y se utiliza para realizar las labores de
inicializacin. El parmetro del tipo javax.servlet.FilterConfig da acceso a cualquier
atributo de configuracin del filtro que se haya especificado en el descriptor de
despliegue o en las anotaciones.

void doFilter(ServletRequest request, ServletResponse response, FilterChain


chain) throws java.io.IOException, ServletException;

Es el mtodo que realiza la lgica especfica del filtro: auditoria, transformaciones,


etc A travs del ltimo parmetro del tipo javax.servlet.FilterChain podremos renviar
la peticin al siguiente filtro en la cadena si lo hubiera, o al componente web destino
que estbamos filtrando.

void destroy();

175

Nuevamente, se invoca una nica vez en la vida del filtro y se utiliza para realizar las
labores de limpieza y liberacin de recursos si fuese necesario.
Como vemos, es muy parecido a un Java Servlet con la diferencia de que no son invocados
expresamente por la presentacin, sino que se ejecutan cuando el componente web al que
filtran es invocado.
Desde la aparicin de Java EE 6.0 existen dos maneras de declarar los filtros y asociarlos a
unos componentes web determinados: el descriptor de despliegue y las anotaciones Java.
Veamos primero cmo se definen y configuran en el descriptor de despliegue, el fichero
web.xml
Definimos el filtro a travs del bloque filter con sus bloques filter-name y filter-class. Y
configuramos qu componentes web filtra mediante el bloque filter-mapping con sus
bloques filter-name y url-pattern.
Por ejemplo:
<?xmlversion="1.0"encoding="UTF8"?>
<webappxmlns:xsi="http://www.w3.org/2001/XMLSchemainstance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/webapp_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/webapp_3_0.xsd"id="WebApp_ID"
version="3.0">
<servlet>
<servletname>DataSourceServlet</servletname>
<servletclass>es.aulamentor.DataSourceServlet</servletclass>
</servlet>
<servletmapping>
<servletname>DataSourceServlet</servletname>
<urlpattern>/DataSourceServlet</urlpattern>
</servletmapping>
<filter>
<filtername>AuditoriaFilter</filtername>

<filterclass>es.aulamentor.AuditoriaFilter</filterclass>
</filter>
<filtermapping>

<filtername>AuditoriaFilter</filtername>

<urlpattern>/*</urlpattern>
</filtermapping>
</webapp>
En este ejemplo, adems de un Java Servlet de un ejemplo anterior, tenemos un Filtro que se
llama AuditoriaFilter implementado mediante la clase es.aulamentor.AuditoriaFilter que filtra (es
decir, intercepta las peticiones) cualquier componente web de la aplicacin.
A travs del patrn de URL, podramos afinar un poco ms el filtrado. Por ejemplo, si
queremos que solo filtre los ficheros HTML, podramos poner *.html en vez de /*, o
/RequestServlet si lo que queremos es filtrar a ese Java Servlet o JavaServer Page concreta.
Hay muchas posibilidades.

176

MDULO C Unidad 7: Java Servlets Avanzado


A continuacin, vamos a ver el cdigo fuente del filtro de este ejemplo, que se limita a escribir
en consola la direccin IP que realiza la peticin y a qu hora, y la hora en la que se enva la
respuesta:
packagees.aulamentor;

importjava.io.IOException;
importjava.util.Calendar;

importjavax.servlet.Filter;
importjavax.servlet.FilterChain;
importjavax.servlet.FilterConfig;
importjavax.servlet.ServletException;
importjavax.servlet.ServletRequest;
importjavax.servlet.ServletResponse;

publicclassAuditoriaFilterimplementsFilter
{
publicvoidinit(FilterConfigfConfig)throwsServletException
{
}

publicvoiddoFilter(ServletRequestrequest,ServletResponse
response,FilterChainchain)throwsIOException,ServletException
{
Calendartime=Calendar.getInstance();
System.out.println("AccesodesdeIP:"+request.getRemoteAddr()+
"alas"+time.get(Calendar.HOUR)+":"++
time.get(Calendar.MINUTE));

chain.doFilter(request,response);

System.out.println("Contestadoalas"+time.get(Calendar.HOUR)+
":"++time.get(Calendar.MINUTE));
}

publicvoiddestroy()
{
}
}
Es muy importante siempre realizar la llamada al siguiente miembro de la cadena (que puede
ser otro filtro o el componente web final) mediante el mtodo doFilter() del parmetro
FilterChain. Aunque tambin existe la posibilidad de desviar la ejecucin, invocando a otro
componente web (por ejemplo de error) a travs del RequestDispatcher como ya sabemos
hacer. Es decir, que un filtro puede decidir en un momento dado interrumpir la ejecucin
normal de la peticin y desviarla por el motivo que sea a otro componente.
La ejecucin en el entorno de desarrollo debera mostrar algo as:

177

Como mencionamos, desde Java EE 6.0 tambin existe la opcin de obviar el descriptor de
despliegue y utilizar anotaciones Java para las definiciones y configuraciones. En este caso,
usaremos la anotacin @WebFilter con sus atributos filterName y urlPatterns:
packagees.aulamentor;

importjava.io.IOException;
importjava.util.Calendar;

importjavax.servlet.Filter;
importjavax.servlet.FilterChain;
importjavax.servlet.FilterConfig;
importjavax.servlet.ServletException;
importjavax.servlet.ServletRequest;
importjavax.servlet.ServletResponse;
importjavax.servlet.annotation.WebFilter;

@WebFilter(filterName="AuditoriaFilter",urlPatterns={"/*"})
publicclassAuditoriaFilterimplementsFilter
{
publicvoidinit(FilterConfigfConfig)throwsServletException
{
}

publicvoiddoFilter(ServletRequestrequest,ServletResponse
178

MDULO C Unidad 7: Java Servlets Avanzado


response,FilterChainchain)throwsIOException,ServletException
{
Calendartime=Calendar.getInstance();
System.out.println("AccesodesdeIP:"+request.getRemoteAddr()+
"alas"+time.get(Calendar.HOUR)+":"++
time.get(Calendar.MINUTE));

chain.doFilter(request,response);

System.out.println("Contestadoalas"+time.get(Calendar.HOUR)+
":"++time.get(Calendar.MINUTE));

publicvoiddestroy()
{
}
}
El resultado debera ser el mismo.
En casos de que existiese ms de un filtro, y que adems filtrasen al mismo componente web,
su ejecucin se realizara en el orden en el que fueron definidos.

7.6

Mantenimiento del estado del cliente

El protocolo HTTP es un protocolo sin estado, es decir, cada peticin que se recibe en el
servidor de un mismo cliente se recibe como si fuese la primera peticin que hace. Es decir,
no hay constancia de que ya se hubiese conectado antes y hubiera solicitado una accin.
Este es un inconveniente importante. Supone por ejemplo, que aunque un cliente ya se
hubiera autenticado con el sistema, como la prxima peticin parece una peticin nueva
pedira autenticarse de nuevo. O que un cliente que mediante una peticin anterior movi un
producto al carrito de la compra en una aplicacin de comercio electrnico, en la siguiente
peticin el carrito aparece vaco.
Por suerte, el protocolo HTTP contempla la posibilidad de almacenar en el lado cliente
informacin del servidor, de manera que dicha informacin viaje a partir de entonces en cada
nueva peticin, y tanto la aplicacin Web como el Servidor de Aplicaciones Java EE puedan
usarla para recordar al cliente.
Esta informacin que se puede almacenar en el lado cliente recibe el nombre de Cookie.

7.6.1 Cookies
Bsicamente, una Cookie es una pareja formada por una clave y un valor que contiene
informacin textual. Es decir, tiene un nombre que identifica la Cookie y un valor asociado,
junto con alguna informacin relacionada adicional que ahora comentaremos sobre cundo
caduca, quin la cre, quin la puede ver, etc

179

El hecho de que se puedan crear desde el servidor, es decir, desde una aplicacin web, las
hace muy tiles para poder recordar los clientes y evitar interacciones redundantes,
prdidas de informacin y similares.
Normalmente (a no ser que tengamos el navegador configurado para evitarlas) en nuestro
navegador tendremos decenas de Cookies guardadas sin que furamos conscientes de ello.
Por ejemplo, si utilizas Mozilla Firefox ves a la opcin de men Firefox -> Options ->
Options:

En la opcin Privacy, selecciona Use custom settings for history en la seccin history,
y entonces pulsa el botn Show Cookies:

180

MDULO C Unidad 7: Java Servlets Avanzado

Te sorprender ver todas las que tienes (incluyendo Cookies de Aula Mentor):

181

En el caso de Internet Explorer, es un poco ms complicado. Ir a la opcin de men tools > Internet Options:

Pulsar el botn Settings de la seccin Browsing history:

182

MDULO C Unidad 7: Java Servlets Avanzado

Y en la nueva ventana, pulsar el botn View files:

183

Se abrir el explorador de archivos, y tendremos que buscar todos aquellos que empiezan
por Cookie:

184

MDULO C Unidad 7: Java Servlets Avanzado

Bien, veamos qu informacin guarda una Cookie antes de meternos con el API Java para
crearlas y acceder a ellas desde nuestras aplicaciones:

Nombre: Identificador de la Cookie para poder ser accedida.

Contenido: La informacin en modo texto que guarda.

Servidor (o Host): Servidor que creo la Cookie.

Ruta (o Path): Dentro de ese Servidor, a qu rango de URLs les mandar el


navegador la Cookie (un / significa que a todas).

Segura: Indica si debe ser enviada exclusivamente a travs de conexiones


seguras (HTTPS).

Caducidad: Indica la fecha en la que caduca y por tanto es borrada. Se puede


indicar en vez de una fecha, que se borre cuando se cierre el navegador.
185

Las Cookies estn implementadas en Java por la clase:


javax.servlet.http.Cookie;
Las

Cookies

ya

existentes

son

accesibles

travs

de

la

peticin

(javax.servlet.http.HttpServletRequest) mediante el mtodo:


Cookie[] getCookies();
Y

las

nuevas,

una

vez

creadas

se

deben

incluir

en

la

respuesta

(javax.servlet.http.HttpServletResponse) mediante el mtodo:


void addCookie(Cookie cookie);
Para crear una Cookie nueva utilizaremos su constructor, pasndole la informacin que ya
hemos comentado:
public Cookie(java.lang.String name, java.lang.String value);
A su vez, la clase Cookie tiene una serie de mtodos para acceder o establecer los distintos
valores que hemos comentado. Lo ms sencillo es verlo en un ejemplo. Vamos a desarrollar
una aplicacin web, que implementa un contador de visitas por parte de un mismo cliente
independientemente de que cerremos el navegador mediante el uso de una Cookie:
<%@pagelanguage="java"contentType="text/html;charset=ISO88591"
pageEncoding="ISO88591"%>
<!DOCTYPEhtmlPUBLIC"//W3C//DTDHTML4.01Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<METAhttpequiv="ContentType"content="text/html;charset=ISO
88591">
<TITLE>Contador</TITLE>
</HEAD>
<BODY>
<%
Cookiecookie=null;

Cookie[]cookies=request.getCookies();

if(cookies!=null)

for(inti=0;i<cookies.length;i++)

if(cookies[i].getName().equals("CONTADOR"))

cookie=cookies[i];

break;

if(cookie==null)

cookie=newCookie("CONTADOR","0");

intcont=Integer.parseInt(cookie.getValue());

cookie.setValue(Integer.toString(cont+1));

cookie.setMaxAge(604800);//Unasemanaensegundos.
186

MDULO C Unidad 7: Java Servlets Avanzado

response.addCookie(cookie);
%>
Nmerodevecesvisitadaestapgina:<%=cookie.getValue()%>
</BODY>
</HTML>
Al ejecutar la aplicacin desde un navegador y recargar (o refrescar) la pgina varias veces,
veremos que el contador sigue contando donde se qued. Es mas, si paramos el servidor y
cerramos el navegador y volvemos a rearrancar todo, el contador debera seguir por donde
iba tambin. Sin embargo, si utilizamos otro navegador distinto o el mismo pero desde otra
mquina de nuestra red, veremos que el contador comienza en cero porque ese navegador
no tiene la Cookie guardada.

Y si le pedimos al navegador que nos muestre todas las Cookies que tiene (filtramos por
CONTADOR) veremos todos los datos de nuestra Cookie.

187

Hay varios puntos importantes que tener presentes de este ejemplo:


Por defecto, el tiempo de expiracin de la Cookie es el de la vida del navegador (tiene
el mismo efecto asignarle un valor negativo), es decir, cuando este se cierra se borra.
Asignarle un valor de cero borrara inmediatamente la Cookie. Y asignarle cualquier
otro valor positivo. es la nueva vida de la Cookie en segundos. En nuestro ejemplo,
hemos establecido que sea una semana tras cada uso.
Cada vez que se modifica algo de la Cookie, hay que aadirla de nuevo a la respuesta.
Si no se aade, la Cookie sigue con los valores antiguos porque la respuesta contiene
una copia de la Cookie recibida y no una referencia.
Por defecto, la ruta (o path) del servidor al que el navegador mandar la Cookie es el
de la aplicacin que creo la Cookie. En nuestro caso, /EjemplosWeb/. Si el navegador
conecta con otra aplicacin en otra ruta o en otro servidor, la Cookie no se enviar.
Aunque el ejemplo que hemos utilizado para presentar las Cookies es muy simple, la
potencia de esta tecnologa es inmensa cuando pensamos en empresas de comercio
electrnico, de marketing, etc Todas ellas llenan nuestro navegador de Cookies con
identificadores que les permiten a nuestro regreso recordar nuestros gustos, lo ltimo que
hicimos en su aplicacin, etc

7.6.2 Sesin HTTP


Las Cookies por tanto, son un mecanismo muy potente para poder recordar al usuario y
actuar en consecuencia. Pero tiene algunos inconvenientes tcnicos como el hecho de solo
188

MDULO C Unidad 7: Java Servlets Avanzado


poder albergar 4Kb de informacin y que dicha informacin solo puede ser textual no muy
estructurada (recordemos que el valor en una Cookie es una simple cadena de caracteres).
Adicionalmente, no son muy seguras. Los usuarios pueden ver el contenido, pueden
borrarlas e incluso pueden modificarlas con mnimos conocimientos de informtica.
Por este motivo, aunque basndose en la existencia de las Cookies, las especificaciones
Java EE definieron un mecanismo de persistencia en el servidor denominado Sesin HTTP (o
HTTP Session). Todos los Servidores de Aplicacin Java EE implementan este servicio.
La sesin HTTP es una zona de almacenaje en el servidor exclusiva de cada cliente, donde
las aplicaciones pueden dejar informacin para ser utilizada en sucesivas peticiones del
mismo cliente.
Cada vez que se recibe una peticin, el servidor analiza las cabeceras HTTP del mensaje en
busca de una Cookie que incluya un identificador de sesin para ponerla a disposicin de la
aplicacin.

Normalmente

dicha

Cookie

se

llama

JSESSIONID

es

gestionada

automticamente por el servidor. Las aplicaciones manejarn la Sesin HTTP desde un


punto de vista funcional, los detalles tcnicos de su mantenimiento quedan cubiertos por el
servicio ofrecido por el servidor.
La Sesin HTTP implementa el interface:
javax.servlet.http.HttpSession;
Es accesible desde la peticin HTTP mediante el mtodo:
HttpSession getSession();
que nos devolver una referencia a la sesin de este cliente si ya existiese o a una nueva
creada en este instante y asignada a este cliente.
Existe otra opcin, que es el mtodo:
HttpSession getSession(boolean create);
La diferencia con el anterior, es que este recibe un boolean como parmetro. Si le
mandamos true, en caso de no existir sesin para este cliente nos devuelve la referencia a
una nueva. Si le mandamos false, nuevamente en caso de no existir, esta vez no la crea y
devuelve null.
Tcnicamente la implementacin de la Sesin HTTP es una especia de coleccin al estilo de
las Hashtables y HashMaps. Es decir, es una coleccin en la que se guardan parejas de
clave y valor, teniendo que ser ambas del tipo java.lang.Object (es decir, tipos complejos).
Tiene distintos mtodos, pero los ms usados son:
java.lang.Object getAttribute(java.lang.String name);
Devuelve el valor de un atributo concreto.
java.util.Enumeration<java.lang.String> getAttributeNames();
189

Devuelve una coleccin con el nombre de todos los atributos que contiene.
void setAttribute(java.lang.String name, java.lang.Object value);
Guarda un atributo con su valor.
void removeAttribute(java.lang.String name);
Elimina un atributo.
void invalidate();
Elimina la sesin del servidor. Recordemos que su creacin no se realiza a travs de
un constructor sino simplemente pidindosela a la peticin HTTP.
Los Servidores de Aplicacin Java EE, implementan un sistema de expiracin de sesiones
inactivas. El motivo es que la sesin consume recursos y no se puede garantizar ni que la
aplicacin web implemente un sistema de limpieza (invocando el mtodo invalidate() cuando
un usuario termine de trabajar con la aplicacin), ni que el usuario de las aplicacin web
siempre termine de manera ordenada la aplicacin invocando la peticin de limpieza (por
ejemplo, un logout) en vez de cerrar el navegador directamente. Sin este sistema de
expiracin, podramos terminar con infinitas sesiones hurfanas en el servidor.
Este tiempo de expiracin, es un parmetro de configuracin propio de cada servidor. En el
caso de Apache Tomcat 7.0.x se realiza en el fichero de configuracin /conf/web.xml que
por defecto viene con media hora de tiempo:
<sessionconfig>
<sessiontimeout>30</sessiontimeout>
</sessionconfig>
Todos los objetos que se guarden en la sesin, deben ser serializables (es decir,
implementar java.io.Serializable). El motivo es que los Servidores de Aplicacin Java EE,
normalmente implementan mecanismos de persistencia de las sesiones para facilitar
mecanismos de balanceo de carga y tolerancia a fallos, para liberar recursos de memoria,
etc.. y si el contenido no es serializable no lo puede guardar.
Como buena prctica, la informacin guardada en la Sesin HTTP debe de ser lo ms
pequea posible.
Veamos un ejemplo similar al que mostramos con las Cookies, pero en esta ocasin aade
un botn para invalidar la sesin y comprobar como se pierde la informacin del contador y
comienza de nuevo en uno.
<%@pagelanguage="java"contentType="text/html;charset=ISO88591"
pageEncoding="ISO88591"%>
<!DOCTYPEhtmlPUBLIC"//W3C//DTDHTML4.01Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<METAhttpequiv="ContentType"content="text/html;charset=ISO
88591">
<TITLE>Contador</TITLE>
190

MDULO C Unidad 7: Java Servlets Avanzado


</HEAD>
<BODY>
<%
HttpSessionsesion=request.getSession(true);
intcont=1;
booleanisInvalidate=false;

if(request.getParameter("invalidate")!=null&&
request.getParameter("invalidate").equals("true"))
{
sesion.invalidate();
isInvalidate=true;
}
else
{
if(sesion.getAttribute("CONTADOR")!=null)
{
cont=
((Integer)sesion.getAttribute("CONTADOR")).intValue();
}
sesion.setAttribute("CONTADOR",newInteger(cont+1));
}
%>
<FORMmethod="POST"action="/EjemplosWeb/sesion.jsp">
<TABLEborder="0">
<%
if(!isInvalidate)
{
%>
<TR>
<TD>Nmerodevecesvisitadaestapgina:<%=cont%></TD>
</TR>
<%
}
%>
<TR>
<TD>Invalidarsesin:<INPUTtype="checkbox"
name="invalidate"value="true"></TD>
</TR>
<TR>
<TD><INPUTtype="submit"value="Refrescar"></TD>
</TR>
</TABLE>
</FORM>
</BODY>
</HTML>
Al ejecutar el ejemplo desde un navegador externo, deberamos ver algo as:

191

Y si le pedimos al navegador que nos muestre todas las Cookies que tiene (filtramos por
localhost) veremos la Cookie JSESSIONID que el Servidor de Aplicaciones Java EE ha
creado para gestionar la Sesin HTTP.

Si invalidamos la sesin mediante la checkbox, adems de comprobar que el contador se


resetea porque su valor se pierde al destruirse la sesin, podremos comprobar como la
192

MDULO C Unidad 7: Java Servlets Avanzado


Cookie JSESSIONID desaparece. De igual modo, si seguimos ejecutando el ejemplo
creando una nueva sesin, el valor de la Cookie (el identificador de la sesin en el servidor)
cambiar.
Otro tema importante a tener en cuenta, es que la Cookie con el identificador de la Sesin
HTTP caduca con la vida del navegador, es decir, si cerramos el navegador, al abrirlo de
nuevo y solicitar la aplicacin, se crea una sesin nueva. Da igual que no la hubiramos
invalidado antes de cerrar. Posiblemente cuando entremos de nuevo en el servidor, siga
existiendo la anterior que todava no habr caducado por el tiempo mximo de inactividad
pero ya no est relacionada con ningn cliente (est hurfana).
Esta es una desventaja importante frente a las Cookies, ya que en las Cookies controladas
por nuestra aplicacin, la expiracin era controlable.
Por eso, normalmente un carrito de la compra, se implementa mediante la Sesin HTTP
porque no tiene sentido que permanezca tras haber realizado una compra. Mientras que los
gustos o preferencias de un cliente se controlan con una Cookie para que perdure entre
compras (normalmente se mantiene un identificador de algn registro en Base de Datos
donde se han ido almacenando todas la navegaciones del cliente por la tienda).
Indicar que en ambos dos casos, las Cookies son utilizadas. En el primer caso la Cookie
guarda toda la informacin del estado del cliente que queremos mantener, mientras que en
la segunda guarda solamente el identificador de la Sesin HTTP del servidor que guarda la
informacin que queremos mantener de cada cliente.

7.7

Gestin de eventos

Las especificaciones Java EE definen una serie de notificacin de eventos a los que las
aplicaciones web se pueden suscribir para ser notificadas de cundo dichos eventos ocurren.
El funcionamiento de la gestin de eventos en las aplicaciones web funciona igual que en las
aplicaciones visuales de escritorio (AWT/Swing). Es decir, siguen ms o menos el siguiente
diagrama:

193

Bsicamente, contamos con dos piezas fundamentales. Un notificador (Notifier), que es quin
generar los eventos, y un escuchador (Listener) que es quien est interesado en dichos
eventos para reaccionar y actuar en consecuencia.
Para que un escuchador, pueda escuchar los eventos de un notificador, ha de subscribirse a
estos. En caso de estar subscrito, el notificador, cuando ocurra el evento, se lo notificar al
escuchador. En Java, esto significa enviar un mensaje concreto al escuchador (ejecutar un
mtodo concreto).
El mecanismo que tenemos en Java de poder garantizar que el escuchador implementa dichos
mtodos, es forzndole a implementar un interfaz. Y esto lo consigue mediante el API del
mtodo de subscripcin, que solo permite recibir parmetros de un tipo concreto. Luego el
escuchador interesado ha de ser de dicho tipo para poder subscribirse.
Un escuchador, igual que se subscribe, puede finalizar la subscripcin.
Los notificadores pasan la informacin a los escuchadores invocando un mtodo concreto
como ya hemos comentado, pasndole como parmetro un evento que encapsula toda la
informacin necesaria para conocer lo que ha ocurrido.
Los eventos contienen informacin sobre lo que ha ocurrido, accesible a travs de distintos
mtodos.
Ahora bien, existe una diferencia muy importante de operativa con las aplicaciones Java SE
(visuales de escritorio), y es que en Java EE no hay que invocar un mtodo para suscribirse
una familia de eventos (addXXXListener), sino que basta con:

194

O informar de quin es el escuchador en el descriptor de despliegue.

O utilizar una anotacin Java en el cdigo del escuchador.

MDULO C Unidad 7: Java Servlets Avanzado


Adicionalmente, no hay forma de finalizar la subscripcin (removeXXXListener) como ocurre
con las aplicaciones visuales. Pero por lo dems, el mecanismo de funcionamiento es el
mismo.
Antes de ver cdigo, vamos a revisar las familias de eventos que existen con sus mtodos. En
concreto, existen tres familias de eventos:
Relacionadas con el Contexto del Java Servlet: por ejemplo, cundo se arranca o se
para la aplicacin.
Relacionadas con la peticin: por ejemplo, cundo se comienza a procesar una
peticin.
Relacionadas con la Sesin HTTP: por ejemplo, cundo se invalida una sesin.
Los tipos de eventos que existen son los siguientes:
javax.servlet.ServletContextEvent

Cuando se arranca o para una aplicacin web.

javax.servlet.ServletContextAttributeEvent

Cuando se crea, modifica o elimina un atributo


del contexto del Java Servlet.

javax.servlet.http.HttpSessionEvent

Cuando se crea o se destruye una sesin.


Tambin cuando se persiste y elimina de la
memoria, y cuando se restaura de nuevo en
memoria.

javax.servlet.http.HttpSessionBindingEvent

Cuando se aade, modifica o eliminan atributos


de la sesin. Tambin cuando un objeto ha sido
aadido o eliminado de la sesin.

javax.servlet.ServletRequestEvent

Cuando se inicializa o destruye una peticin.

javax.servlet.ServletRequestAttributeEvent

Cuando se aade, modifica o elimina un atributo


de la peticin.

A continuacin aadiremos una tabla con un listado de todos los interfaces que hay para cada
una de las familias de eventos que hemos visto, y sus mtodos:

javax.servlet.ServletContextListener

contextDestroyed
contextInitialized
attributeAdded

javax.servlet.ServletContextAttribute

attributeRemoved
attributeReplaced

javax.servlet.http.HttpSessionActivationListener

javax.servlet.http.HttpSessionBindingListener

sessionDidActivate
sessionWillPassivate
valueBound
valueUnbound

195

attributeAdded
javax.servlet.http.HttpSessionAttributeListener

attributeRemoved
attributeReplaced

javax.servlet.ServletRequestListener

requestDestroyed
requestInitialized
attributeAdded

javax.servlet.ServletRequestAttributeListener

attributeRemoved
attributeReplaced

No nos detendremos en explicar uno a uno cada mtodo. El API Java EE esta disponible en la
web, as que no lo reproduciremos por completo aqu.
Veamos eso si, cmo se suscribe una clase a un notificador mediante el descriptor de
despliegue y mediante anotaciones Java:

Mediante descriptor de despliegue. Utilizaremos el bloque listener con su bloque


listener-class:
<listener>
<listenerclass>
es.aulamentor.EjemploListener
</listenerclass>
</listener>
Y la clase es.aulamentor.EjemploListener ya implementar los interfaces necesarios
para las acciones que quiera escuchar.

Mediante anotaciones Java (recordemos que esta opcin solo est disponible desde
Java EE 6.0). Utilizaremos la anotacin @Weblistener
importjavax.servlet.annotation.WebListener;

@WebListener
publicclassEjemploListenerimplements
Y la clase es.aulamentor.EjemploListener ya implementar los interfaces necesarios
para las acciones que quiera escuchar.

Veamos un ejemplo que escucha todos los eventos posibles, y muestra por consola una lnea
por cada evento que ha ocurrido. Lo ejecutaremos junto con la aplicacin que demostraba el
uso de la Sesin HTTP para ver qu eventos se van lanzando:
packagees.aulamentor;

importjavax.servlet.ServletContextAttributeEvent;
importjavax.servlet.ServletContextAttributeListener;
importjavax.servlet.ServletContextEvent;
importjavax.servlet.ServletContextListener;
importjavax.servlet.ServletRequestAttributeEvent;
importjavax.servlet.ServletRequestAttributeListener;
importjavax.servlet.ServletRequestEvent;
196

MDULO C Unidad 7: Java Servlets Avanzado


importjavax.servlet.ServletRequestListener;
importjavax.servlet.annotation.WebListener;
importjavax.servlet.http.HttpSessionActivationListener;
importjavax.servlet.http.HttpSessionAttributeListener;
importjavax.servlet.http.HttpSessionBindingEvent;
importjavax.servlet.http.HttpSessionBindingListener;
importjavax.servlet.http.HttpSessionEvent;
importjavax.servlet.http.HttpSessionListener;

@WebListener
publicclassEjemploListenerimplementsServletContextListener,
ServletContextAttributeListener,HttpSessionListener,
HttpSessionAttributeListener,HttpSessionActivationListener,
HttpSessionBindingListener,ServletRequestListener,
ServletRequestAttributeListener
{
publicvoidrequestDestroyed(ServletRequestEventev)
{
System.out.println("SehainvocadorequestDestroyed...");
}

publicvoidattributeAdded(HttpSessionBindingEventev)
{
System.out.println("SehainvocadoattributeAdded...");
}

publicvoidcontextInitialized(ServletContextEventev)
{
System.out.println("SehainvocadocontextInitialized...");
}

publicvoidsessionDidActivate(HttpSessionEventev)
{
System.out.println("SehainvocadosessionDidActivate...");
}

publicvoidvalueBound(HttpSessionBindingEventev)
{
System.out.println("SehainvocadovalueBound...");
}

publicvoidattributeAdded(ServletContextAttributeEventev)
{
System.out.println("SehainvocadoattributeAdded...");
}

publicvoidattributeRemoved(ServletContextAttributeEventev)
{
System.out.println("SehainvocadoattributeRemoved...");
}

publicvoidsessionDestroyed(HttpSessionEventev)
{
System.out.println("SehainvocadosessionDestroyed...");
}

publicvoidattributeRemoved(HttpSessionBindingEventev)
{
System.out.println("SehainvocadoattributeRemoved...");
}

197

publicvoidattributeAdded(ServletRequestAttributeEventev)
{
System.out.println("SehainvocadoattributeAdded...");
}

publicvoidvalueUnbound(HttpSessionBindingEventev)
{
System.out.println("SehainvocadovalueUnbound...");
}

publicvoidsessionWillPassivate(HttpSessionEventev)
{
System.out.println("SehainvocadosessionWillPassivate...");
}

publicvoidsessionCreated(HttpSessionEventev)
{
System.out.println("SehainvocadosessionCreated...");
}

publicvoidattributeReplaced(HttpSessionBindingEventev)
{
System.out.println("SehainvocadoattributeReplaced...");
}

publicvoidattributeReplaced(ServletContextAttributeEventev)
{
System.out.println("SehainvocadoattributeReplaced...");
}

publicvoidattributeRemoved(ServletRequestAttributeEventev)
{
System.out.println("SehainvocadoattributeRemoved...");
}

publicvoidcontextDestroyed(ServletContextEventev)
{
System.out.println("SehainvocadocontextDestroyed...");
}

publicvoidattributeReplaced(ServletRequestAttributeEventev)
{
System.out.println("SehainvocadoattributeReplaced...");
}

publicvoidrequestInitialized(ServletRequestEventev)
{
System.out.println("SehainvocadorequestInitialized...");
}
}
La ejecucin en el entorno de desarrollo debera mostrar algo as:

198

MDULO C Unidad 7: Java Servlets Avanzado

199

200

PARA RECORDAR

La informacin de configuracin de un Java Servlet que es recogida mediante el


mtodo getInitParameter del parmetro javax.servlet.ServletConfig, que es
pasado al mtodo init del Java Servlet. Para pasar dicha informacin, el
administrador puede hacerlo en el despliegue de la aplicacin o el desarrollador
puede hacerlo en el descriptor de despliegue o mediante anotaciones.

Aunque el servidor de aplicaciones Java EE permite y posibilita la concurrencia en


las llamadas a un Java Servlet, hay que tener cuidado con la definicin de
atributos o cdigo que no se quiera que sea multithread.

Hemos visto dos alternativas de acceso a Bases de datos:


Acceso directo desde el cdigo. Su principal problema es su pobre rendimiento.
Acceso a travs de un Pool de conexin, siendo esta la recomendada para las
aplicaciones

Java

EE.

El

mtodo

utilizado

es

el

getConnection

de

javax.sql.DataSource

Los filtros son unos componentes que se despliegan como parte de la aplicacin
Web, y cuya misin es interceptar las peticiones y respuesta de un componente
concreto para por ejemplo, realizar algn tipo de validacin, algn tipo de auditoria,
algn tipo de transformacin, etc

Un filtro de implementar el interface: javax.servlet.Filter que incluye tres mtodos:

init: Se invoca una nica vez en la vida del filtro y se utiliza para realizar las
labores de inicializacin.

doFilter: Es el mtodo que realiza la lgica especfica del filtro: auditoria,


transformaciones, etc

destroy: Se invoca una nica vez en la vida del filtro y se utiliza para realizar las
labores de limpieza y liberacin de recursos si fuese necesario.

201

Para el mantenimiento del estado del cliente en el servidor, se pueden utilizar:


Cookies: es informacin formada por una clave y un valor que contiene
informacin textual. Esta cookie es creada en el servidor de aplicaciones y
almacenada en el navegador cliente utilizado en las llamadas a la aplicacin
web.
Sesin HTTP: Es una zona de almacenaje en el servidor exclusiva de cada
cliente, donde las aplicaciones pueden dejar informacin para ser utilizada en
sucesivas peticiones del mismo cliente.

Las especificaciones Java EE definen una serie de notificacin de eventos a los que
las aplicaciones web se pueden suscribir para ser notificadas de cundo dichos
eventos ocurren. Contamos con dos piezas fundamentales:
Un notificador (Notifier), que es quin generar los eventos
Un escuchador (Listener) que es quien est interesado en dichos eventos para
reaccionar y actuar en consecuencia.

En concreto, existen tres familias de eventos:


Relacionadas con el Contexto del Java Servlet
Relacionadas con la peticin
Relacionadas con la Sesin HTTP

202

Unidad de Aprendizaje 8

JAVASERVER PAGES
AVANZADO

NDICE
8.1

Introduccin ................................................................. 205

8.2

Etiquetas JSP estndar .............................................. 205

8.3

Lenguaje de Expresiones JSP (EL) ........................... 208

8.4

Libreras de etiquetas JSP estndar......................... 211


8.4.1 Core ................................................................................214
8.4.2 XML.................................................................................215
8.4.3 I18N.................................................................................215
8.4.4 Database ........................................................................216
8.4.5 Functions........................................................................217

8.5

Libreras de etiquetas JSP personalizadas.............. 218

PARA RECORDAR.................................................................. 224

MDULO C Unidad 8: JavaServer Pages Avanzado

8.1

Introduccin

A menudo, en el desarrollo de aplicaciones web de una cierta envergadura, existen equipos de


desarrollo con roles y skills diferentes. As, nos encontraremos con desarrolladores expertos
en Java que se encargarn normalmente del modelo y controlador, mientras que tendremos
otro grupo de desarrolladores expertos en diseo que se encargarn de la presentacin.
Estos expertos en diseo, no suelen conocer ni manejar el lenguaje Java, centrando sus skills
ms en diseo grfico, tratamiento de imgenes, etc por lo que al desarrollar la presentacin
emplearn herramientas ms orientadas a etiquetas que a programar con el lenguaje Java.
Por este motivo, la especificacin de JavaServer Pages (JSP) define una serie de mecanismos
para seguir permitiendo el desarrollo de la presentacin sin necesidad de escribir lneas de
lenguaje Java.
Estos mecanismos son:

Las acciones JSP estndar.

Las libreras de etiquetas JSP

Esta unidad se centra en el estudio de ambos mecanismos.

8.2

Etiquetas JSP estndar

Las etiquetas JSP estndar, son etiquetas del estilo de las empleadas en las pginas HTML o
en los descriptores de despliegue (XML) que permiten realizar acciones en el momento de
ejecucin de la pgina.
Cualquier etiqueta JSP podra ser sustituida sin ningn problema por cdigo Java equivalente
como ya hicimos en unidades anteriores.
La sintaxis de una etiqueta JSP consiste en el prefijo jsp: seguido del identificador de la
accin y opcionalmente atributos (parejas de nombre y valor).
Las especificaciones definen mltiples etiquetas JSP estndar, a saber:

<jsp:forward>: redirige la peticin a otra pgina JSP, HTML o Java Servlet.

<jsp:include>: incluye el resultado de otra pgina JSP, Java Servlet u otro componente
web esttico.

<jsp:param>: se utiliza dentro de un bloque de <jsp:forward> o <jsp:include> para


indicar los parmetros que opcionalmente se pueden enviar.

<jsp:useBean>: referencia o instancia una clase Java y la asocia un nombre y un


mbito concreto.

<jsp:setProperty>: inserta un valor a un atributo del bean (o clase Java).

<jsp:getProperty>: recoge el valor de un atributo del bean (o clase Java) y lo incluye en


la respuesta
205

<jsp:text>: inserta texto en la respuesta.

<jsp:element>: inserta un elemento XML en la respuesta.

<jsp:plugin>: inserta un Applet Java en la respuesta.

<jsp:output>: inserta la etiqueta XML DOCTYPE de toda JSP en la respuesta.

<jsp:body>: identifica el comienzo del cuerpo del documento HTML (viene a sustituir a
<BODY>). Se ha de utilizar siempre que en la pgina se utilice la accin
<jsp:attribute>.

Otras: <jsp:root>, <jsp:invoke>, <jsp:doBody>, <jsp:attribute>,

Son muchas las etiquetas pero trataremos solo algunas de ellas porque en general, a
excepcin de unas pocas, su uso es muy raro.
La etiqueta <jsp:include> produce un efecto exactamente igual que el de la directiva <%@
include file=xxx %> que ya hemos visto y practicado en alguna actividad durante el curso.
La diferencia es que el atributo que necesita se llama page.
Algunos ejemplos:
<jsp:includepage="copyright.html"/>
<jsp:includepage="/index.html"/>
<jsp:includepage="/login.jsp">
<jsp:paramname="usuario"value="pepe"/>
</jsp:include>
Y la etiqueta <jsp:forward> es parecida a <jsp:include> con la diferencia de que no incluye el
resultado, sino que delega en ese nuevo recurso la respuesta.
Algunos ejemplos:
<jsp:forwardpage="/servlet/login"/>
<jsp:forwardpage="/servlet/login">
<jsp:paramname="usuario"value="pepe"/>
</jsp:forward>
Otra etiqueta tpica es la de referenciar o instanciar una clase Java para trabajar con ella.
Como vimos en la enumeracin de etiquetas existentes, la etiqueta a emplear es
<jsp:useBean>. Esta etiqueta busca un objeto con el identificador dado en el mbito
seleccionado y de no encontrarlo, lo crea con dicho identificador en dicho mbito.
Utiliza por tanto estos tres atributos:

206

id: identificador del objeto.

scope: mbito donde buscar o crearlo. Existen cuatro valores posibles:


o

request: la peticin.

page: la pgina:

session: la sesin HTTP.

MDULO C Unidad 8: JavaServer Pages Avanzado


o

application: la aplicacin.

class: la clase Java (el tipo).

Por ejemplo:
<jsp:useBeanid="cesta"scope="session"class="edu.aulamentor.Cesta"/>
Esta etiqueta busca en la sesin HTTP un objeto de la clase edu.aulamentor.Cesta que se
llama cesta. Si no existiera lo crea.
Y esto para qu? Pues normalmente va a acompaado de las etiquetas <jsp:setProperty> y
<jsp:getProperty> para utilizar el objeto en cuestin.
<jsp:setProperty> nos permite establecer el valor de alguno de los atributos del objeto. Para
ello utiliza tres atributos:

name: identificador del objeto.

attribute: atributo del objeto.

value: valor del atributo del objeto.

Por ejemplo:
<jsp:useBeanid="cesta"scope="session"class="edu.aulamentor.Cesta"/>
<jsp:setPropertyname="cesta"property="total"value="0.0"/>

De igual forma, podemos acceder al valor de un atributo del objeto mediante la accin
<jsp:getAttribute>. Para ello utiliza dos atributos:

name: identificador del objeto.

attribute: atributo del objeto.

Por ejemplo:
Totaldelacestaes:<jsp:getPropertyname="cesta"property="total"/>
Para que estas etiquetas funcionen bien, la clase Java debe seguir las especificaciones
JavaBean. Esto significa que, entre otras cosas, la clase debe tener un constructor por defecto
(constructor sin parmetros) y un getter/setter por cada atributo (siguiendo la norma de utilizar
get y set seguido del nombre del atributo con la primera letra en maysculas). Es decir, en
nuestro ejemplo:
packagees.aulamentor;

publicclassCesta
{
privatedoubletotal;

publicCesta()
{
}

207

publicdoublegetTotal()
{
returnthis.total;
}

publicvoidsetTotal(doubleparam)
{
this.total=param;
}
}
Simplemente por comparar, este mismo ejemplo pero con cdigo Java habra sido algo as:
<%
es.aulamentor.Cestacesta=
(es.aulamentor.Cesta)session.getAttribute(cesta);
cesta.setTotal(0.0);
%>
Totaldelacestaes:<%=cesta.getTotal()%>
Pero la etiqueta <jsp:setProperty> puede tener un uso ms potente todava, y es el de
transferir el valor de los parmetros de un formulario que se reciba en una peticin a los
atributos de un objeto Java sin necesidad de ir uno a uno. Basta con eliminar el atributo value:
<jsp:useBeanid="cesta"scope="session"class="es.aulamentor.Cesta"/>
<jsp:setPropertyname="cesta"property="*"/>
En este caso, el servidor va a buscar todos (porque hemos usado el carcter * en vez de un
nombre concreto) aquellos parmetros que vengan en la peticin que se llamen igual que
algn atributo de la clase Cesta y ponerle su valor.

8.3

Lenguaje de Expresiones JSP (EL)

Conocido con el acrnimo EL (Expression Language).


EL es un pseudolenguaje para identificar y acceder de una manera muy sencilla a las variables.
Veamos primero un ejemplo con el que se ver rpidamente la idea. Mediante cdigo Java,
para acceder por ejemplo al atributo nombre, de un objeto de tipo Perro guardado en un
atributo llamado perro en un objeto de tipo Persona que est guardado en la Sesin HTTP con
el identificador de persona escribiramos algo as:
Sellama:<%=
((es.aulamentor.Persona)session.getAttribute(persona)).getPerro().getN
ombre()%>
Sin embargo, utilizando EL sera algo as:
Sellama:${persona.perro.nombre}
Sencillo, verdad?

208

MDULO C Unidad 8: JavaServer Pages Avanzado


La sintaxis y opciones de EL son realmente sencillas. Ahora, es muy importante no pensar en
Java cuando usemos EL y viceversa, porque aunque se parecen son distintos y nos llevarn a
equivocaciones.
Las expresiones EL siempre van entre llaves ({ }) precedidas del smbolo del dlar ($):
${}
El contenido de las llaves siempre ser uno o varios identificadores separados por puntos.
El primer identificador puede ser dos cosas:

Una referencia a un objeto implcito: que existe en el contenedor web y es accesible


directamente.

Un atributo existente en uno de los distintos mbitos: pgina, peticin, sesin o


aplicacin. Es importante tener en cuenta que se busca en ese orden, por si existiese
ms de un atributo con el mismo nombre en mbitos diferentes.

Todos los objetos implcitos son una coleccin del tipo Map, es decir, contiene parejas de
clave y valor. Estos son los que hay:

pageScope: mbito de la pgina.

requestScope: mbito de la peticin.

sessionScope: mbito de la sesin.

applicationScope: mbito de la aplicacin.

param: parmetros de la peticin.

paramValues: parmetros de la peticin en caso de que el parmetro sea a su vez una


coleccin.

header: cabeceras de la peticin.

headerValues: cabeceras de la peticin en caso de que la cabecera sea a su vez una


coleccin.

cookie: cookies de la peticin.

initParam: parmetros del contexto.

pageContext: es el nico que no es un Map. Directamente es una referencia a una


instancia de la clase javax.servlet.jsp.PageContext

Por tanto, si queremos referenciar al atributo persona que est en la Sesin HTTP tenemos
dos opciones:
${persona}
o para evitar colisiones en el caso de que existiese otro atributo con el mismo nombre en
mbitos con mayor precedencia:
209

${sessionScope.persona}
Ahora, si queremos seguir profundizando en el atributo, accediendo a otros atributos ms
internos en su estructura (como el ejemplo anterior donde accedimos al nombre del perro de la
persona), es cuando utilizaremos una secuencia de nombres de atributos separados por
puntos:
${sessionScope.persona.perro.nombre}
Ahora bien, llegados a este punto es importante volver a recordar, que esto solo funciona si las
clases Java accedidas siguen las especificaciones JavaBean, que entre otras cosas obligan a
que:

La clase tenga un constructor por defecto (sin parmetros).

La clase tenga un mtodo getter por cada atributo siguiendo la regla de que se llamara
get seguido del nombre del atributo con la primera letra en mayscula.

La clase tenga un mtodo setter por cada atributo siguiendo la regla de que se llamara
set seguido del nombre del atributo con la primera letra en mayscula.

Por tanto, para que funcione el ejemplo:


${sessionScope.persona.perro.nombre}
significa que la clase Persona tiene un mtodo que se llama getPerro() y que la clase Perro
tiene un mtodo que se llama getNombre(). Si esto no fuese as, la compilacin de la pgina
JSP fallara.
Veamos otro ejemplo de cmo sera el acceso al valor de una Cookie. Usando Java sera algo
as:
<%
Cookie[]cookies=request.getCookies();
for(inti=0;i<cookies.lenght;i++)
{
if((cookies[i].getName()).equals(nombreUsuario))
{
%>
<%=cookies[i].getValue()%>
<%
}
}
%>
Con EL sera simplemente esta lnea:
${cookie.nombreUsuario.value}
Las expresiones EL tambin admiten el uso de corchetes ([]). Su uso vale para dos cosas:

210

MDULO C Unidad 8: JavaServer Pages Avanzado

Lo

mismo

que

el

punto,

es

decir,

${perro.nombre}

es

equivalente

${perro[nombre]} usando las comillas dobles para especificar el nombre del


atributo.

Para profundizar en atributos que son de algn tipo de coleccin (array, Map o List),
por ejemplo: ${perros[3].nombre}

Las expresiones EL tambin permiten implementar una mnima lgica, aunque no est
recomendado su uso para ello. Soporta los operadores aritmticos (+, -, *, / y %), los
operadores lgicos (&&, || y !) y los operadores relacionales (==, =, <, >, <= y >=).
Otro dato a tener muy en cuenta es que las expresiones EL pueden ser usadas como valores
de los atributos de las etiquetas JSP que ya hemos comentado en la seccin anterior y en las
que comentaremos a continuacin.

8.4

Libreras de etiquetas JSP estndar

Al igual que existen las etiquetas JSP estndar definidas en las especificaciones JSP, con el
tiempo surgi otra especificacin denominada JSTL (JavaServer Page Standard Tag Library o
Librera de etiquetas JSP estndar) que aglutina una serie de libreras de etiquetas o acciones
adicionales que persiguen el mismo objetivo que las anteriores: facilitar la programacin de la
presentacin de las aplicaciones web a diseadores grficos sin conocimientos del lenguaje
Java mediante herramientas visuales orientadas al manejo de etiquetas.
En este curso no pretendemos cubrir todas y cada una de las etiquetas, pero si comentar
cmo se especifica el uso de una librera, qu libreras hay, y algn ejemplo.
La gua de referencia completa de JSTL est disponible en:
http://docs.oracle.com/javaee/5/jstl/1.1/docs/tlddocs/
Actualmente existen cinco libreras de etiquetas presentes en cualquier servidor de
aplicaciones Java EE completo:

Core (en castellano principal): Su prefijo es c y su URI http://java.sun.com/jsp/jstl/core.


Cubre funcionalidades bsicas como el manejo de variables, el control del flujo, la
gestin de URLs y otras acciones.

XML: Su prefijo es x y su URI http://java.sun.com/jsp/jstl/xml. Cubre funcionalidades


de gestin de ficheros XML.

I18N

(en

castellano

internacionalizacin):

Su

prefijo

es

fmt

su

URI

http://java.sun.com/jsp/jstl/fmt. Cubre funcionalidades de formateo de mensajes,


nmeros, fechas, horas, etc teniendo en cuenta la localizacin de cada cliente.

Database

(en

castellano,

Base

de

Datos):

Su

prefijo

es

sql

su

URI

http://java.sun.com/jsp/jstl/sql. Cubre funcionalidades de acceso a Bases de Datos.

211

Functions

(en

castellano

funciones):

Su

prefijo

es

fn

su

URI

http://java.sun.com/jsp/jstl/functions. Cubre funcionalidades relacionadas con el


manejo de cadenas de caracteres.
Antes de entrar ms en detalle en cada librera, vamos a ver cmo se indica en una pgina JSP
el uso de una librera. Para ello se utiliza una directiva que ya mencionamos en una unidad
anterior pero que no explicamos en detalle taglib:
<%@tagliburi=xxxprefix=xxx%>
Recibe dos atributos:
URI: identificador del espacio de nombres (viene a significar algo parecido a los
paquetes Java para evitar colisiones de dos etiquetas de mismo nombre).
prefix: identificador de la librera a utilizar.
Por tanto, si en nuestra pgina JSP queremos utilizar por ejemplo las libreras Core y Database
deberamos aadir estas dos lneas al inicio de la pgina:
<%@tagliburi="http://java.sun.com/jsp/jstl/core"prefix="c"%>
<%@tagliburi="http://java.sun.com/jsp/jstl/sql"prefix="sql"%>
El uso de una accin concreta de una de estas libreras, sigue la sintaxis de las acciones JSP
estndar: pero cambiando jsp por el prefijo de la librera, seguido de los dos puntos,
seguidos de la accin en cuestin, seguida de sus atributos.
Por ejemplo, el uso de la accin set de la librera Core sera algo as:
<c:setvar="titulo"value="DonQuijote"/>
Pero qu pasa cuando aadimos una de estas directivas en Eclipse IDE for Java EE
Developers? Salen errores.
El motivo, es que Apache Tomcat no cumple el 100% de las especificaciones Java EE, y en
concreto JSTL 1.2 no lo cumple. Pero es muy sencillo aadir la implementacin de referencia
de la especificacin a nuestra aplicacin web, aadiendo a /WebContent/WEB-INF/lib estos
dos ficheros JAR:

http://search.maven.org/remotecontent?filepath=javax/servlet/jsp/jstl/javax.servlet.jsp.j
stl-api/1.2.1/javax.servlet.jsp.jstl-api-1.2.1.jar

http://search.maven.org/remotecontent?filepath=org/glassfish/web/javax.servlet.jsp.jst
l/1.2.1/javax.servlet.jsp.jstl-1.2.1.jar

212

MDULO C Unidad 8: JavaServer Pages Avanzado

Una vez hemos copiado ambos dos ficheros en el directorio /WebContent/WEB-INF/lib del
proyecto, si no se fuese el error forzamos una recompilacin mediante la opcin de men:
Project -> Clean:

Revisemos a continuacin brevemente las etiquetas de cada una de las libreras estndar.
Como ya comentamos, no va a ser una explicacin exhaustiva. Simplemente pretendemos
que se conozcan qu posibilidades hay y dnde poder consultar en caso de llegar a
necesitarse alguna.

213

8.4.1 Core
Implementa acciones bsicas para el tratamiento de variables, control de flujo, gestin de
URLs, y otras:
Gestin de variables:
o set: estable el valor de una variable EL o del atributo de una variable EL en uno
de los mbitos posibles. Si dicha variable no existiese la crea.
<c:setvar="titulo"scope="session"value="${param.titulo}"/>
o remove: elimina una variable EL.
<c:removevar="cart"scope="session"/>
Control de flujo:
o choose junto con when y otherwise: viene a ser una especie de estructura
switch, case, default de Java. Evala las condiciones EL de cada etiqueta
when y entra por la que sea true. Si ninguna fuese true, ejecuta la otherwise.
<c:choose>
<c:whentest="${cont==0}">
Nosehaencontradoningnelemento.
</c:when>
<c:otherwise>
Sehanencontrado${cont}elementos.
</c:otherwise>
</c:choose>
o forEach: permite iterar por una coleccin de elementos.
<c:forEachvar="libro"items="${sessionScope.cesta.libros}">
<TR>
<TDalign="right"bgcolor="#ffffff">
${libro.titulo}
</TD>
</TR>
</c:forEach>
o forTokens: permite iterar por una coleccin de tokens separados por un
delimitador.
o if: evala una condicin EL y si es true sigue ejecutando el contenido del
bloque.
<c:iftest="${param.nombre==Pepe}">
<H1>ElnombreesPepe.</H1>
</c:if>
Gestin de URLs:
o import: importa el contenido de un recurso de Internet en una variable EL.
Puede utilizar param para especificar parmetros.
<c:importurl="/introduccion.txt"var="texto"/>
o redirect: enva al cliente un cdigo HTTP de redireccin. Puede utilizar param
para especificar parmetros.
214

MDULO C Unidad 8: JavaServer Pages Avanzado


o url: guarda URLs en una variable EL. Puede utilizar param para especificar
parmetros.
Otras:
o catch: captura una excepcin. La excepcin no se propaga y por tanto no se
invocar la pgina JSP de error si la hubiera.
o out: evala una expresin EL y devuelve su valor.
Ms detalles y ejemplos:
http://docs.oracle.com/javaee/5/jstl/1.1/docs/tlddocs/

8.4.2 XML
Implementa acciones bsicas para el parseo de documentos XML, control de flujo
recorriendo estructuras XML y transformaciones:
Parseo:
o out: evala una expresin XPath y su resultado lo devuelve como parte de la
respuesta.
o parse: parsea un documento XMl y guarda el contenido en una variable
identificada mediante EL.
o set: evala una expresin XPath y su resultado lo guarda en una variable
identificada mediante EL.
Control de flujo:
o choose junto con when y otherwise: similar a la librera Core pero itera sobre el
resultado de evaluar una expresin XPath sobre un documento XML.
o forEach: similar a la librera Core pero itera sobre el resultado de evaluar una
expresin XPath sobre un documento XML.
o if: similar a la librera Core pero itera sobre el resultado de evaluar una
expresin XPath sobre un documento XML.
Transformacin:
o transform: aplica una transformacin a un documento XML especificado en el
atributo doc definida en una plantilla XSLT especificada en el atributo xslt.
Ms detalles y ejemplos:
http://docs.oracle.com/javaee/5/jstl/1.1/docs/tlddocs/

8.4.3 I18N
Implementa acciones bsicas para la gestin de la localizacin, seleccionar los mensajes a
mostrar en base a dicha localizacin y el formateo de nmeros y fechas:
Localizacin:
o setLocale: fuerza una localizacin concreta independientemente de la que
enviara el cliente web.
o requestEncoding: especifica la codificacin a utilizar para interpretar los
parmetros de una peticin.
Mensajes:
215

o bundle: especifica el conjunto de recursos localizados a utilizar.


o setBundle: similar a bundle pero para un contexto especfico.
o message: sirve para aadir a la respuesta un texto localizado especificando
en el atributo key la clave de dicho texto dentro del bundle.
Formateo:
o formatNumber: formatea un nmero teniendo en cuenta la localizacin.
o formatDate: formatea una fecha teniendo en cuenta la localizacin.
o parseNumber: convierte una cadena de texto en un nmero teniendo en
cuenta la localizacin.
o parseDate: convierte una cadena de texto en una fecha teniendo en cuenta la
localizacin.
o setTimeZone: especifica la zona horaria.
Ms detalles y ejemplos:
http://docs.oracle.com/javaee/5/jstl/1.1/docs/tlddocs/

8.4.4 Database
Implementa acciones bsicas para el acceso a las Bases de Datos:
Configuracin:
o setDataSource: sirve para especificar el identificador JNDI del Data Source a
utilizar.
<sql:setDataSourcedataSource="jdbc/TestDB"/>
SQL:
o query: ejecuta una query que devuelve un resultado que guarda en el atributo
var. Dicho resultado es un Java Bean con los siguientes atributos (a tener en
cuenta para poder explotar la informacin resultante mediante EL):
public String[] columnNames
public int rowCount
public Map[] rows()
public Object[][] rowsByIndex
public boolean limitedByMaxRows
Un ejemplo imaginando que tenemos una tabla LIBROS con columnas como
AUTOR, TITULO y PAGINAS:
<sql:queryvar="libros"sql="select*fromLIBROSwhereAUTOR=
?">
<sql:paramvalue="${autor}"/>
</sql:query>
<c:forEachvar="libro"begin="0"items="${libros.rows}">
<H2>${libro.titulo}</H2><BR>
Nm.DePginas:${libro.paginas}<BR><BR>
</c:forEach>
216

MDULO C Unidad 8: JavaServer Pages Avanzado


o update: ejecuta una actualizacin en la Base de Datos.
o transaction: sirve para aglutinar varias queries y/o updates en una unidad
transaccional.
Ms detalles y ejemplos:
http://docs.oracle.com/javaee/5/jstl/1.1/docs/tlddocs/

8.4.5 Functions
Implementa acciones bsicas de manejo de cadenas de caracteres pero al contrario que
todas las libreras anteriores, ests no son etiquetas como tal sino funciones a emplear en
una EL:

length: devuelve la longitud de una coleccin.


<c:iftest="${fn:length(parametro.nombre)>0}">
Longituddelnombremayordecero.Correcto!
</c:if>

toUpperCase: devuelve la cadena en maysculas.

toLowerCase: devuelve la cadena en minsculas.

substring: devuelve una parte de una cadena.

substringAfter: devuelve una parte de una cadena a partir de un carcter


especificado.

substringBefore: devuelve una parte de una cadena antes de un carcter


especificado.

trim: devuelve la cadena sin espacios en blanco por delante ni por detrs.

replace: devuelve una cadena con un carcter/cadena remplazado por otro.

indexOf: devuelve la posicin de un carcter/cadena especificado.

startsWith: chequea si una cadena comienza con un carcter/cadena especificado.

endsWith: chequea si una cadena termina con un carcter/cadena especificado.

contains: chequea si una cadena contiene un carcter/cadena especificado.

containsIgnoreCase: chequea si una cadena contiene un carcter/cadena


especificado ignorando las maysculas y minsculas.

split: divide una cadena devolviendo un array de cadenas.

join: devuelve la unin de varias cadenas en una sola cadena.

escapeXml: devuelve la cadena habiendo cambiado los caracteres especiales por


sus valores codificados para poder ser usados en una URL.

Ms detalles y ejemplos:
http://docs.oracle.com/javaee/5/jstl/1.1/docs/tlddocs/

217

8.5

Libreras de etiquetas JSP personalizadas

Al igual que existen las libreras de etiquetas JSP estndar estudiadas en la seccin anterior,
las especificaciones Java EE contemplan la posibilidad de que podamos definir e implementar
nuestra propia librera de etiquetas. De esta forma, en caso de haber decidido minimizar el
cdigo Java que aparecer en las pginas JSP podemos implementar etiquetas que cubran
necesidades particulares de nuestra aplicacin.
De igual forma, encontraremos en Internet cantidad de libreras adicionales de etiquetas
desarrolladas por terceras personas.
El API necesario para la implementacin de etiquetas personalizadas se encuentra en el
paquete: javax.servlet.jsp.tagext;
La implementacin de una etiqueta personalizada siempre ha de implementar el interface:
javax.servlet.jsp.tagext.Tag
o extender la clase:
javax.servlet.jsp.tagext.TagSupport
que es una clase que contiene implementaciones por defecto de los mtodos del interface
Tag.
El interface Tag tiene varios mtodos, pero aqu solo comentaremos:

int doStartTag() throws JspException


Este mtodo es invocado cuando el contenedor web detecta el inicio de la etiqueta. Lo
normal, es usar este mtodo para implementar la lgica asociada a la etiqueta. Debe
devolver un nmero entero que corresponde a una de estas constantes definidas en el
interface Tag:
o

SKIP_BODY: significa que la etiqueta ya ha procesado el resto de etiquetas o


contenido incluido dentro de su bloque (si lo hubiera) as que el contenedor
web puede proceder con el final de la etiqueta.

EVAL_BODY_INCLUDE: significa que la etiqueta no ha procesado el resto de


etiquetas o contenido incluido dentro de su bloque (si lo hubiera) as que el
contendor web debe procesar ese contenido antes de proceder con el final de
la etiqueta.

int doEndTag() throws JspException


Este mtodo es invocado cuando el contenedor web detecta el final de la etiqueta.
Debe devolver un nmero entero que corresponde a una de estas constantes definidas
en el interface Tag:
o

EVAL_PAGE: indica al contendor web que contine con el proceso de


ejecucin normal de la pgina JSP.

218

MDULO C Unidad 8: JavaServer Pages Avanzado


o

SKIP_PAGE: indica al contendor web que interrumpa el proceso de ejecucin


normal de la pgina JSP.

Si la nueva etiqueta va a soportar atributos, entonces la implementacin Java debe incluir un


atributo con un mtodo setter con idntico nombre por cada uno. El mtodo setter debe seguir
las especificaciones JavaBean, es decir, debe llamarse set seguido del nombre del atributo
con la primera letra en maysculas.
El contenedor web, al encontrarse con la nueva etiqueta, instanciar la implementacin y
especificar los valores de todos los atributos basado en los valores que se encuentran en la
etiqueta en la pgina JSP.
Al extender la clase TagSupport, tenemos acceso a una variable con nombre pageContext de
tipo:
javax.servlet.jsp.PageContext
que nos permite acceder al writer (java.io.Writer) de la respuesta, para poder escribir el
resultado de la ejecucin de la etiqueta mediante el mtodo:
public JspWriter getOut()
Veamos un ejemplo. Vamos a definir e implementar una etiqueta que aada por delante y por
detrs del contenido de su cuerpo (el bloque definido por la etiqueta) un carcter un nmero
concreto de veces. Para ello, tendr dos atributos donde especifiquemos el carcter y el
nmero de veces llamados caracter y veces.
Esta sera la implementacin:
packagees.aulamentor;

importjava.io.IOException;
importjava.io.Writer;

importjavax.servlet.jsp.JspException;
importjavax.servlet.jsp.tagext.Tag;
importjavax.servlet.jsp.tagext.TagSupport;

publicclassRepiteTagextendsTagSupport
{
privatecharcaracter;
privateintveces;

publicvoidsetCaracter(charcarcater)
{
this.caracter=carcater;
}

publicvoidsetVeces(intveces)
{
this.veces=veces;
}

publicintdoStartTag()throwsJspException
{
219

Writerout=pageContext.getOut();
for(inti=0;i<veces;i++)
{
try
{
out.write(caracter);
}
catch(IOExceptionex)
{
ex.printStackTrace();
}
}
returnTag.EVAL_BODY_INCLUDE;
}

publicintdoEndTag()throwsJspException
{
Writerout=pageContext.getOut();
for(inti=0;i<veces;i++)
{
try
{
out.write(caracter);
}
catch(IOExceptionex)
{
ex.printStackTrace();
}
}
returnTag.EVAL_PAGE;
}
}
A continuacin, necesitamos crear un fichero de configuracin XML donde se le indica al
Servidor Java EE la existencia de una librera personalizada y los detalles. Este fichero de
extensin *.tld debe formar parte de la aplicacin web y su ubicacin es un directorio tlds en
/WEB-INF
En nuestro caso lo llamamos AulaMentorTagLib.tld:

220

MDULO C Unidad 8: JavaServer Pages Avanzado

Este fichero, sigue una sintaxis concreta. Veamos el contenido para nuestro ejemplo y
repasaremos las etiquetas ms relevantes:
<?xmlversion="1.0"encoding="UTF8"?>
<taglibversion="2.1"xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchemainstance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/webjsptaglibrary_2_1.xsd">
<tlibversion>1.0</tlibversion>
<shortname>Aula_Mentor_Tag_Library</shortname>
<uri>http://www.aulamentor.es/jsp/jstl/tags</uri>
<tag>
<name>repite</name>
<tagclass>es.aulamentor.RepiteTag</tagclass>
<bodycontent>scriptless</bodycontent>
<attribute>
<name>caracter</name>
<required>true</required>
</attribute>
<attribute>
<name>veces</name>
<required>false</required>
</attribute>
</tag>
</taglib>
La primera lnea indica que se trata de un archivo XML.
La segunda indica que se trata de la definicin de una librera de etiquetas.
Como bloques o etiquetas relevantes tenemos:

uri: a la que luego haremos referencia desde la pgina JSP para indicar que usamos
esta librera.
221

tag: incluye la definicin de una etiqueta personalizada.

name: el identificador de la etiqueta cuando la usemos en una pgina JSP.

tag-class: la clase Java que implementa el comportamiento de la etiqueta.

body-content: indica si la etiqueta puede albergar contenido dentro de su bloque o no


(entre la etiqueta de inicio y la de cerrado). Puede tomar varios valores:
o

empty: no puede tener contenido.

scriptless: puede tener contenido pero solo otras etiquetas, no cdigo de


script.

tagdependent: puede contener cualquier cosa.

attribute: incluye la definicin de un atributo de la etiqueta. Indica su nombre que


usaremos luego en la pgina JSP y si es obligatorio o no.

Por ltimo, ya solo nos queda utilizar la nueva etiqueta en la aplicacin. Para ello vamos a
crear una pgina JSP muy sencilla:
<%@pagelanguage="java"contentType="text/html;charset=ISO88591"
pageEncoding="ISO88591"%>
<%@tagliburi="http://www.aulamentor.es/jsp/jstl/tags"prefix="am"%>
<!DOCTYPEhtmlPUBLIC"//W3C//DTDHTML4.01Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<METAhttpequiv="ContentType"content="text/html;charset=ISO
88591">
<TITLE>PruebadeTagPersonalizada</TITLE>
</HEAD>
<BODY>
<am:repitecaracter="*"veces="5">
PRUEBA
</am:repite>
<BODY>
</HTML>
Primero, fijmonos en cmo decimos que vamos a utilizar etiquetas de la nueva librera:
<%@tagliburi="http://www.aulamentor.es/jsp/jstl/tags"prefix="am"%>
La URI debe coincidir exactamente con la que especificamos en le fichero de configuracin de
la librera. Y el prefijo, puede ser cualquiera. En este caso hemos decidido que sea: am.
Ahora, veamos dnde y cmo hemos usado la etiqueta:
<am:repitecaracter="*"veces="5">
PRUEBA
</am:repite>
Identificada con el prefijo y utilizando exactamente el mismo nombre que usamos en el fichero
de configuracin. Hemos usado tambin sus dos atributos (solo carcter era obligatorio).

222

MDULO C Unidad 8: JavaServer Pages Avanzado


El resultado de su ejecucin, debera ser la palabra PRUEBA rodeada de cinco asteriscos por
delante y detrs:

El API para la creacin de etiquetas personalizadas es ms extenso de lo que hemos visto en


esta seccin. Aqu hemos repasado las bases para la creacin de etiquetas sencillas, pero el
API ofrece ms posibilidades que si el alumno est interesado puede profundizar consultando
la gua de referencia en Internet:
http://docs.oracle.com/javaee/6/api/javax/servlet/jsp/tagext/packagesummary.html#package_description

223

PARA RECORDAR

Las etiquetas JSP estndar, son etiquetas del estilo de las empleadas en las
pginas HTML o en los descriptores de despliegue (XML) que permiten realizar
acciones en el momento de ejecucin de la pgina. Su sintaxis consiste en el prefijo
jsp:.

Las Expression Language (EL) son un pseudolenguaje para identificar y acceder


de una manera muy sencilla a las variables. Su sintaxis es ${}

La especificacin JSTL (JavaServer Page Standard Tag Library o Librera de


etiquetas JSP estndar) aglutina una serie de libreras de etiquetas o acciones
adicionales. Se especifican mediante la directiva taglib.

Las libreras existentes en un servidor de aplicaciones Java EE son:


Core: Cubre funcionalidades bsicas como el manejo de variables, el control del
flujo, la gestin de URLs y otras acciones.
XML: Cubre funcionalidades de gestin de ficheros XML.
I18: Cubre funcionalidades de formateo de mensajes, nmeros, fechas, horas,
etc teniendo en cuenta la localizacin de cada cliente.
Database: Cubre funcionalidades de acceso a Bases de Datos.
Functions: Cubre funcionalidades relacionadas con el manejo de cadenas de
caracteres.

Las especificaciones Java EE contemplan la posibilidad de que podamos definir


implementar nuestra propia librera de etiquetas. La implementacin de una etiqueta
personalizada siempre ha de implementar el interface, javax.servlet.jsp.tagext.Tag
o extender la clase javax.servlet.jsp.tagext.TagSupport

224

Unidad de Aprendizaje 9

OTROS CONCEPTOS AVANZADO

NDICE
9.1

Introduccin ................................................................. 227

9.2

Gestin de errores....................................................... 227

9.3

Gestin de la seguridad.............................................. 232

9.4

Frameworks de desarrollo web................................. 244


9.4.1 JavaServer Faces .........................................................244
9.4.2 Apache Struts................................................................245
9.4.3 Spring Source................................................................245
9.4.4 Apache Wicket ..............................................................246

PARA RECORDAR.................................................................. 247

MDULO C Unidad 9: Otros conceptos

9.1 Introduccin
Esta es la ltima unidad del curso. En ella trataremos algunos temas no menos importantes
que no han tenido cabida en las unidades anteriores como son la gestin de errores y la
seguridad en Java EE.
Por ltimo, daremos una breve pincelada de algunos frameworks de desarrollo de aplicaciones
web, que construidos sobre los conceptos que hemos visto en este curso pretenden acelerar y
facilitar el desarrollo de aplicaciones web. La idea es simplemente que el alumno conozca de
su existencia y profundice en alguno de ellos si los encuentra de inters. Cada uno de ellos por
si solo, dara lugar a un curso completo.

9.2

Gestin de errores

Segn las especificaciones Java EE, existen dos alternativas no excluyentes para la gestin de
errores:

Programtica: Toda la gestin se lleva dentro de la aplicacin mediante cdigo


fuente. Es el modo que hemos estado empleando hasta ahora en todos los
ejemplos de las distintas unidades.

Declarativa: La gestin se externaliza en configuraciones en el descriptor de


despliegue.

Evidentemente cada una tiene sus ventajas e inconvenientes. Por un lado, la programtica es
la gestin ms potente y flexible, sin embargo el cdigo es ms complejo y la lgica ms
complicada de seguir. Por otro lado, la declarativa es la gestin ms sencilla pero por otro
lado tiene ms restricciones.
La gestin programtica ya la conocemos. Mediante las estructura try & catch o cualquier otro
medio de deteccin de errores, realizamos mediante cdigo redirecciones a pginas concretas
de tratamiento y muestra del error. Por tanto, en esta unidad nos vamos a ceir a la gestin
declarativa.
Mediante la gestin declarativa podemos controlar dos aspectos:

Errores HTTP: Qu eran y qu tipos de errores HTTP existan ya lo estudiamos en


la unidad dedicada al protocolo HTTP en este mismo curso. Es el propio Servidor
de Aplicaciones Java EE el que habitualmente gestiona este tipo de errores
mostrando una pgina de error. Pero las especificaciones Java EE nos permiten
definir en el descriptor de despliegue un componente web (pgina HTML, pgina
JSP, Java Servlet, etc) que se invocar cuando ocurra dicho error en vez de
mostrar la pgina por defecto del servidor.

Por ejemplo, la pgina por defecto para un error 404 (recurso no encontrado) de
Apache Tomcat 7.0.x es la siguiente:

227

Sin embargo, mediante los bloques error-page y sus bloques error-code (para
especificar el cdigo de error) y location (para especificar qu componente web
invocar) podemos cambiar este comportamiento por defecto.
Veamos un ejemplo de cmo cambiar la pgina que se muestra para el error HTTP
404:
<?xmlversion="1.0"encoding="UTF8"?>
<webappxmlns:xsi="http://www.w3.org/2001/XMLSchemainstance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/webapp_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/webapp_3_0.xsd"
id="WebApp_ID"version="3.0">
<errorpage>
<errorcode>404</errorcode>
<location>/Error404.jsp</location>
</errorpage>
</webapp>
Y esta es la pgina JSP:
<%@pagelanguage="java"contentType="text/html;charset=ISO
88591"pageEncoding="ISO88591"%>
<!DOCTYPEhtmlPUBLIC"//W3C//DTDHTML4.01Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<METAhttpequiv="ContentType"content="text/html;
charset=ISO88591">
<TITLE>Pginanoencontrada.Disculpelas
molestas...</TITLE>
</HEAD>
<BODY>
Pginanoencontrada.Disculpelasmolestas...<BR/>
Sielproblemeapersistepngaseencontactoconel
administrador.<BR/>
<%=Calendar.getInstance().getTime()%>
</BODY>
</HTML>
228

MDULO C Unidad 9: Otros conceptos


Este sera el resultado ahora:

Y as podramos hacer con todos los tipos de errores HTTP ms habituales,


consiguiendo dar una imagen ms corporativa y cercana al usuario (evidentemente la
pgina de nuestro ejemplo no es ninguna de las dos cosas).

Excepciones Java: Tambin se pueden gestionar de manera declarativa las


excepciones Java que se produzcan. Lo ms habitual, es hacerlo con aquellas
excepciones

Java

no

esperadas

con

difcil

solucin.

Por

ejemplo,

java.lang.NullPointerException. Pero podemos gestionar cualquiera que queramos.


Veamos primero cmo contesta por defecto Apache Tomcat 7.0.x a una excepcin del
tipo java.lang.NullPointerException no capturada.

229

El mecanismo para declarar qu componente invocar cuando se produzca una


excepcin concreta, es similar al visto anteriormente. La nica diferencia es que en vez
del bloque error-code usaremos exception-type.
Otra diferencia, es que el Servidor de Aplicaciones Java EE nos pasar en la peticin
dos atributos (ojo, no parmetros):
o

javax.servlet.error.exception: Conteniendo la excepcin que se ha


producido (no el nombre, sino la instancia como tal).

javax.servlet.error.request_uri: Indicando el componente que produjo el


error.

Veamos un ejemplo de cmo cambiar la pgina que se muestra para la excepcin


java.lang.Exception no capturada y tratada en el cdigo:
<?xmlversion="1.0"encoding="UTF8"?>
<webappxmlns:xsi="http://www.w3.org/2001/XMLSchemainstance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/webapp_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/webapp_3_0.xsd"
id="WebApp_ID"version="3.0">
<errorpage>
<exception-type>java.lang.NullPointerException</exception-type>
<location>/NullPointerException.jsp</location>
</errorpage>
</webapp>
Y esta es la pgina JSP:
<%@pageimport="java.util.Calendar"%>
<%@pagelanguage="java"contentType="text/html;charset=ISO
88591"pageEncoding="ISO88591"%>
<!DOCTYPEhtmlPUBLIC"//W3C//DTDHTML4.01Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<METAhttpequiv="ContentType"content="text/html;
charset=ISO88591">
<TITLE>Errornoesperado.</TITLE>
</HEAD>
<BODY>
<%
Exceptionex=(Exception)request.getAttribute
("javax.servlet.error.exception");
StackTraceElement[]stack=ex.getStackTrace();
%>
Seprodujounerrornoesperado.Disculpenlas
molestias...<BR/>
Contacteconeladministradorconlasiguiente
informacin:<BR/>
<UL>
<LI>Componentedefectuoso:
<%=
request.getAttribute("javax.servlet.error.request_uri")
%>
230

MDULO C Unidad 9: Otros conceptos


</LI>
<LI>Errorproducido:NullPointerException</LI>
<LI>Msdetalle:<BR/>
<%
for(inti=0;i<stack.length;i++)
{
%>
<%=stack[i].toString()%><BR/>
<%
}
%>
</LI>
</UL>
<%=Calendar.getInstance().getTime()%>
</BODY>
</HTML>
Este sera el resultado ahora:

Y as podramos hacer con todos los tipos de excepciones ms habituales no


controlados o que se pueden escapar mas fcilmente en el cdigo, consiguiendo dar
una imagen ms corporativa y cercana al usuario (evidentemente la pgina de nuestro
ejemplo no es ninguna de las dos cosas).

231

9.3

Gestin de la seguridad

La seguridad, es un tema que no podemos descuidar cuando hablamos de aplicaciones web.


Y las especificaciones Java EE tampoco la descuidan para nada. Imaginemos lo que podra
pasar con aplicaciones web tpicas de hoy en da sin una buena gestin de la seguridad: home
banking, brker online, tiendas virtuales, etc
En general, desde un punto de vista terico, una buena gestin de la seguridad debe cubrir los
siguientes puntos:

Autenticacin: Asegurarse que un cliente es quien dice ser.

Por ejemplo, al acceder a una aplicacin web se nos puede solicitar identificador y
contrasea para validar que somos quien decimos ser. Existen otras opciones adems
del identificador y contrasea, como son los certificados digitales.

Autorizacin: Asegurarse que un cliente accede solo a los recursos a los que
puede/debe tener acceso y no a otros.

Por ejemplo, si no somos administradores de una aplicacin web, al entrar en el


sistema no deberamos poder acceder a opciones de configuracin de la aplicacin.

Integridad de datos: Asegurarse que los mensajes llegan sin haber sido alterados
por el camino.

Por ejemplo, evitar que alguien pueda estar pinchado a la red y modifique el
contenido de los mensajes que enviamos a un servidor.

Confidencialidad: Asegurarse que solo las personas autorizadas pueden ver y


acceder a informacin sensible.

Por ejemplo, evitar que alguien pueda estar pinchado a la red y lea informacin
sensible como contraseas, nmeros de cuenta y similares que fluye entre nuestro
navegador y el servidor.

No repudio: Asegurarse que quedan evidencias que eviten que un cliente pueda
negar haber realizado una transaccin contra el servidor.

Por ejemplo, evitar que alguien pueda decir que no hizo algo en nuestro sistema.

Auditoria: Asegurarse que queda registrado todos los eventos relacionados con la
seguridad para posteriores estudios y anlisis.

Por ejemplo, registrar todos los intentos de acceso fallidos al sistema.


No trataremos en profundidad todos los puntos pero si nos centraremos en algunos
imprescindibles como son la autenticacin y autorizacin. Otros como la integridad de datos o
la confidencialidad los comentaremos brevemente ya que no dependen tanto de la aplicacin
sino de una correcta configuracin de la infraestructura.
Las especificaciones Java EE, nos ofrecen dos aproximaciones distintas al tema de la
seguridad:
232

MDULO C Unidad 9: Otros conceptos

Programtica: es decir, define una serie de APIs para que la gestin de la


seguridad se realice directamente desde el cdigo. APIs como Java Authentication
and Authorization Service (JAAS) para realizar autenticacin y autorizacin, Java
Cryptography Extension (JCE) para realizar cifrados, Java Security Socket
Extension (JSSE) para realizar comunicaciones seguras, etc

Declarativa: es decir, la posibilidad de delegar en los contenedores Java EE


(Servidor de Aplicaciones Java EE) algunos de los temas relacionados con la
gestin de la seguridad, permitiendo a los desarrolladores centrarse en la lgica de
negocio de la aplicacin y no en estos temas colaterales pero no menos
importantes.

La aproximacin declarativa se realiza mediante el uso de los descriptores de


despliegue o las anotaciones Java (a partir de Java EE 6.0).
Ambas dos aproximaciones tienes pros y contras. La aproximacin declarativa no cubre el
100% de las reas ni es tan flexible como la programtica, pero es mucho ms sencilla, est
sujeta a menos errores y cubre las necesidades habituales de autenticacin y autorizacin.
En este curso vamos a tratar solamente la aproximacin declarativa, ya que no tiene sentido
dedicar ms unidades a estudiar APIs tan especficas. No obstante, todas estn
documentadas en la web:
http://docs.oracle.com/javase/7/docs/technotes/guides/security/
Antes de entrar en los detalles Java EE, vamos a revisar unos conceptos tericos previos
imprescindibles como son: Realm, Usuario, Grupo y Rol.

Realm: Recibe el nombre en ingls de Realm, el conjunto de usuarios y grupos


identificados como vlidos para una aplicacin web junto con las polticas de
seguridad asociadas. Podramos decir que se trata de toda la configuracin de
seguridad de una aplicacin web concreta.

Usuario: Es el identificador unvoco de una persona o entidad de software que puede


interactuar con la aplicacin.

Grupo: Es el identificador de un conjunto de usuarios que tienen algo en comn.

Rol: Es el identificador de un concepto abstracto que agrupa a varios usuarios


individuales o grupos. Se utiliza para realizar la autorizacin de acceso a los recursos.

Cmo encajan estos conceptos juntos y cmo se utilizan para securizar una aplicacin web?
En el Servidor de Aplicaciones Java EE gestionado por los administradores de sistemas
existen definidos usuarios y grupos. Dependiendo del Servidor de Aplicaciones Java EE y de la
solucin corporativa que haya instalada en cada caso, esto usuarios y grupos estarn
definidos directamente en el servidor o estn delegados en el Sistema Operativo, o en un
Servidor de Directorio LDAP. Lo importante en nuestro caso es que ambos dos conceptos son
un tema ajeno a la aplicacin web y est delegado en la infraestructura.
233

Los roles sin embargo, si que son algo que definimos en la aplicacin. Es un concepto
abstracto de quin puede hacer qu. Es decir, en la aplicacin diremos que a un recurso
concreto solo puede acceder el rol A y B. Y a otro recurso distinto solo el rol A o por el
contrario el rol C.
El truco llega en el momento de la instalacin de la aplicacin donde el administrador
encargado de dicho proceso mapear el concepto abstracto de rol, con los conceptos reales
de usuario y/o grupo.
Y el conjunto de esas definiciones para una aplicacin concreta, es lo que llamamos un Realm.
Pero vayamos por partes. Ha quedado claro que primero necesitamos contar con una serie de
usuarios y opcionalmente grupos en nuestro sistema.
En el caso de este curso, estamos usando el Servidor de Aplicaciones Java EE Apache
Tomcat 7.0.x que ofrece distintas alternativas de configuracin. Optaremos por la ms
sencilla, que consiste en el uso de un fichero de configuracin de usuarios: /conf/tomcatusers.xml
La primera dificultad viene porque Apache Tomcat denomina rol lo que en la teora de
seguridad hemos llamado grupo. No pasa nada, pero evidentemente crea confusin. As que
es importante recordarlo a lo largo del resto de esta seccin: lo que en la configuracin de
Apache Tomcat se denomina rol, realmente corresponde al concepto que hemos comentado
de grupo. No tiene nada que ver con el concepto abstracto de rol que aplica a las aplicaciones
web y que veremos mas adelante.
Vamos a trabajar sobre un ejemplo donde tendremos seis usuarios: usuario1, usuario2,
usuario3, usuario4, usuario5 y usuarios6, y tres grupos: clientes (representa usuarios normales
de nuestra aplicacin), operadores (representa usuarios especiales que pertenecen a nuestra
empresa y que tienen ms permisos que los usuarios cliente) y administradores (representa
usuarios nuevamente de nuestra empresa que tienen todos los permisos).
Los dos primeros usuarios pertenecen al primer grupo, los dos siguientes al segundo grupo y
los dos ltimos al tercero. Las contraseas de cada usuario son su propio identificador, es
decir, usuario1 tendr como contrasea usuario1, y as sucesivamente.
Vamos a editar el fichero de configuracin en el entorno de desarrollo Eclipse IDE for Java EE
Developers (recordemos que los ficheros de configuracin de Apache Tomcat en este caso
estarn en un proyecto denominado Servers):

234

MDULO C Unidad 9: Otros conceptos

El contenido del fichero debera ser algo as para nuestro ejemplo:


<?xmlversion="1.0"encoding="UTF8"?>
<tomcatusers>
<rolerolename="clientes"/>
<rolerolename="operadores"/>
<rolerolename="administradores"/>
<userusername="usuario1"password="usuario1"roles="clientes"/>
<userusername="usuario2"password="usuario2"roles="clientes"/>
<userusername="usuario3"password="usuario3"roles="operadores"/>
<userusername="usuario4"password="usuario4"roles="operadores"/>
<userusername="usuario5"password="usuario5"
roles="administradores"/>
<userusername="usuario6"password="usuario6"
roles="administradores"/>
</tomcatusers>
De esta manera, nuestro sistema ya cuenta con los usuarios y grupos definidos. Nota: Un
usuario puede pertenecer a ms de un grupo. En ese caso, simplemente se aadira un grupo
separado por coma a la definicin del usuario.
A continuacin, vamos a desarrollar nuestra aplicacin de ejemplo antes de seguir avanzando
en la configuracin de la seguridad. La aplicacin va a ser muy sencilla, va a consistir en una
pgina HTML de entrada con tres botones: clientes, operadores y administradores. Esta
pgina es pblica, es decir, ser accesible por todo el mundo est dado de alta en los
sistemas como usuario o no.
Cada uno de los tres botones, invocar a una JavaServer Page (JSP) distinta accesible por
cada uno de los tres grupos. Y aqu vendr el grueso del ejemplo porque los clientes solo
podrn acceder a la pgina de clientes, los operadores podrn acceder tanto a la de clientes
235

como a la de operadores y los administradores a todas. Para ello, el navegador nos pedir un
usuario y una contrasea, para saber quin somos y si nos puede autorizar o no. Pero la
configuracin para que esto ocurra la veremos despus de escribir el cdigo.
Pgina HTML (publica.html):
<!DOCTYPEhtmlPUBLIC"//W3C//DTDHTML4.01Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<METAhttpequiv="ContentType"content="text/html;charset=ISO
88591">
<TITLE>EjemplodeSeguridad</TITLE>
</HEAD>
<BODY>
Estapginaespblicayaccesibleportodoelmundo.
<FORMmethod="POST"action="/EjemplosWeb/clientes.jsp">
<INPUTtype="submit"value="Clientes">
</FORM>
<FORMmethod="POST"action="/EjemplosWeb/operadores.jsp">
<INPUTtype="submit"value="Operadores">
</FORM>
<FORMmethod="POST"action="/EjemplosWeb/administradores.jsp">
<INPUTtype="submit"value="Adminitradores">
</FORM>
</BODY>
</HTML>
Pgina JSP (clientes.jsp):
<%@pagelanguage="java"contentType="text/html;charset=ISO88591"
pageEncoding="ISO88591"%>
<!DOCTYPEhtmlPUBLIC"//W3C//DTDHTML4.01Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<METAhttpequiv="ContentType"content="text/html;charset=ISO
88591">
<TITLE>EjemplodeSeguridad</TITLE>
</HEAD>
<BODY>
PginadeClientesaccesibleporusuarios:
<UL>
<LI>Usuario1</LI>
<LI>Usuario2</LI>
<LI>Usuario3</LI>
<LI>Usuario4</LI>
<LI>Usuario5</LI>
<LI>Usuario6</LI>
</UL>
</BODY>
</HTML>
Pgina JSP (operadores.jsp):
<%@pagelanguage="java"contentType="text/html;charset=ISO88591"
pageEncoding="ISO88591"%>
<!DOCTYPEhtmlPUBLIC"//W3C//DTDHTML4.01Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
236

MDULO C Unidad 9: Otros conceptos


<HTML>
<HEAD>
<METAhttpequiv="ContentType"content="text/html;charset=ISO
88591">
<TITLE>EjemplodeSeguridad</TITLE>
</HEAD>
<BODY>
PginadeClientesaccesibleporusuarios:
<UL>
<LI>Usuario3</LI>
<LI>Usuario4</LI>
<LI>Usuario5</LI>
<LI>Usuario6</LI>
</UL>
</BODY>
</HTML>
Pgina JSP (administradores.jsp):
<%@pagelanguage="java"contentType="text/html;charset=ISO88591"
pageEncoding="ISO88591"%>
<!DOCTYPEhtmlPUBLIC"//W3C//DTDHTML4.01Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<METAhttpequiv="ContentType"content="text/html;charset=ISO
88591">
<TITLE>EjemplodeSeguridad</TITLE>
</HEAD>
<BODY>
PginadeClientesaccesibleporusuarios:
<UL>
<LI>Usuario5</LI>
<LI>Usuario6</LI>
</UL>
</BODY>
</HTML>
La clave viene ahora con el descriptor de despliegue, donde definiremos los roles que existen
en nuestra aplicacin, las restricciones de seguridad de los componentes de la aplicacin, y el
modo de autenticacin al acceder a la aplicacin.
Los roles existentes en una aplicacin web, se definen mediante los bloques security-role y
role-name. En nuestro ejemplo:
<securityrole>
<rolename>clientes</rolename>
</securityrole>
<securityrole>
<rolename>operadores</rolename>
</securityrole>
<securityrole>
<rolename>administradores</rolename>
</securityrole>
Como ya comentamos en los conceptos tericos, Grupo y Rol no tienen por qu ser lo mismo.
Los roles son un concepto abstracto independiente de los sistemas de usuarios/grupos que
237

haya definidos en una empresa De esta manera se consigue una independencia entre la
aplicacin y los sistemas donde se vaya a desplegar.
Es a la hora de instalar la aplicacin, donde se hace un mapeo de roles con usuarios/grupos.
Pero cmo se hace este mapeo es dependiente de cada Servidor de Aplicaciones Java EE.
Cada uno lo realiza en un fichero de configuracin distinto y con una sintaxis distinta. Pero es
ms, en el caso de Apache Tomcat 7.0.x dicho mapeo no existe y nos obliga a que los roles
correspondan con nombres de grupos idnticos lo cual es una restriccin importante.
Las restricciones de acceso a los componentes de la aplicacin web se definen mediante el
bloque security-constraint, el cual a su vez contiene mltiples bloques. Veamos un ejemplo:
<securityconstraint>
<webresourcecollection>
<webresourcename>AreadeOperadores</webresourcename>
<urlpattern>/operadores.jsp</urlpattern>
<httpmethod>GET</httpmethod>
<httpmethod>POST</httpmethod>
</webresourcecollection>
<authconstraint>
<rolename>administradores</rolename>
<rolename>operadores</rolename>
</authconstraint>
<userdataconstraint>
<transportguarantee>NONE</transportguarantee>
</userdataconstraint>
</securityconstraint>
Como se puede observar, primero se define el recurso o conjunto de recursos a proteger,
identificados por una URL que podra usar comodines tipo: /*, o /*.jsp, etc especificando
adems los protocolos HTTP de acceso a tener en consideracin.
Despus de especifican los roles que tienen autorizacin a acceder a los recursos definidos
anteriormente.
Y por ltimo, especifica si las comunicaciones deben ser seguras o no (utilizando HTTPS). Este
bloque puede tomar tres valores:

NONE: no existe requerimiento de comunicaciones seguras para acceder a los


recursos definidos, es decir, HTTP.

CONFIDENTIAL: las comunicaciones deben no ser legibles, por tanto se debe usar
HTTPS para acceder a los recursos definidos.

INTEGRAL: las comunicaciones deben asegurar su integridad, es decir, que nadie


pueda haber cambiado el contenido por en medio entre el cliente y el servidor. A
efectos prcticos implica lo mismo que CONFIDENTIAL, se debe usar HTTPS para
acceder a los recursos definidos.

De esta manera, definiramos todas las posibles autorizaciones de acceso a los componentes
de la aplicacin web.
238

MDULO C Unidad 9: Otros conceptos


El modo de autenticacin se define mediante los bloques login-config y auth-method. Por
ejemplo, para que sea el navegador el que nos muestre una ventana de autenticacin de
usuario y contrasea:
<loginconfig>
<authmethod>BASIC</authmethod>
</loginconfig>
Existen mltiples mtodos de autenticacin. Brevemente son:

BASIC: el servidor pedir al cliente que solicite el usuario y contrasea. Estas viajaran
codificadas en Base64 en claro (a no ser que las comunicaciones sean seguras).

FORM: la aplicacin web implementa la pgina de solicitud de usuario y contrasea,


en vez de ser una ventana del navegador. La configuracin en el descriptor de
despliegue requiere algn parmetro adicional que veremos ms tarde.

CLIENT-CERT: requiere que el navegador enve un certificado digital con la


informacin del usuario. Este es el mecanismo que se utiliza por ejemplo en
aplicaciones como la declaracin de Hacienda en la AEAT.

DIGEST: la informacin del usuario y la contrasea van cifradas utilizando alguno de


los algoritmos soportados por ambos lados, cliente y servidor.

Con todo esto, veamos cmo sera el descriptor de despliegue de nuestro ejemplo:
<?xmlversion="1.0"encoding="UTF8"?>
<webappxmlns:xsi="http://www.w3.org/2001/XMLSchemainstance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/webapp_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/webapp_3_0.xsd"id="WebApp_ID"
version="3.0">
<securityrole>
<rolename>clientes</rolename>
</securityrole>
<securityrole>
<rolename>operadores</rolename>
</securityrole>
<securityrole>
<rolename>administradores</rolename>
</securityrole>
<securityconstraint>
<webresourcecollection>
<webresourcename>AreadeAdminitradores</webresourcename>
<urlpattern>/administradores.jsp</urlpattern>
<httpmethod>GET</httpmethod>
<httpmethod>POST</httpmethod>
</webresourcecollection>
<authconstraint>
<rolename>administradores</rolename>
</authconstraint>
<userdataconstraint>
<transportguarantee>NONE</transportguarantee>
</userdataconstraint>
</securityconstraint>
239

<securityconstraint>
<webresourcecollection>
<webresourcename>AreadeOperadores</webresourcename>
<urlpattern>/operadores.jsp</urlpattern>
<httpmethod>GET</httpmethod>
<httpmethod>POST</httpmethod>
</webresourcecollection>
<authconstraint>
<rolename>administradores</rolename>
<rolename>operadores</rolename>
</authconstraint>
<userdataconstraint>
<transportguarantee>NONE</transportguarantee>
</userdataconstraint>
</securityconstraint>
<securityconstraint>
<webresourcecollection>
<webresourcename>AreadeClientes</webresourcename>
<urlpattern>/clientes.jsp</urlpattern>
<httpmethod>GET</httpmethod>
<httpmethod>POST</httpmethod>
</webresourcecollection>
<authconstraint>
<rolename>administradores</rolename>
<rolename>operadores</rolename>
<rolename>clientes</rolename>
</authconstraint>
<userdataconstraint>
<transportguarantee>NONE</transportguarantee>
</userdataconstraint>
</securityconstraint>
<loginconfig>
<authmethod>BASIC</authmethod>
</loginconfig>
</webapp>

Como se puede ver, definimos tres roles, tres colecciones de recursos con sus definiciones de
acceso y el mtodo de autenticacin BASIC.
Si ejecutamos el ejemplo siguiendo la siguiente secuencia lgica:
1. Accedemos a la pgina HTML principal pblica que no est protegida. Deberamos
poder acceder y ver su contenido sin ningn tipo de problema.

240

MDULO C Unidad 9: Otros conceptos


2. Solicitamos el acceso a la zona de Clientes ya protegida. Y el navegador debera
mostrarnos una ventanita de autenticacin. Nos autenticamos con usuario3/usuario3,
es decir, con un miembro del grupo de operadores. Y deberamos poder ver la zona de
clientes sin problemas.

3. Navegamos hacia atrs y solicitamos el acceso a la zona de Operadores. Deberamos


poder acceder nuevamente sin problemas ya que el usuario3 pertenece al grupo de
operadores.

241

4. Por ltimo, navegamos hacia atrs y solicitamos el acceso a la zona de


Administradores. En este caso deberamos recibir un error HTTP 403 porque no
tenemos autorizacin para acceder a esa zona.

Se trata de un ejemplo muy sencillo pero bastante ilustrativo de la gestin de la seguridad en


Java EE de forma declarativa.
Antes de dar por finalizada esta seccin, vamos a mostrar el uso del mecanismo de
autenticacin FORM (el del ejemplo anterior ha sido BASIC). Como indicbamos, FORM
implica que la ventana de peticin de usuario y contrasea es proporcionada por la aplicacin
web y no es una ventanita del navegador.
El primer paso es modificar el descriptor de despliegue. En este caso debera ser algo as:
<loginconfig>
<authmethod>FORM</authmethod>
<formloginconfig>
<formloginpage>/login.jsp</formloginpage>
<formerrorpage>/loginerroneo.jsp</formerrorpage>
</formloginconfig>
</loginconfig>
Como configuracin adicional, especificamos los componentes web que muestran la pantalla
de autenticacin, y la pantalla de error en caso de que la autenticacin sea errnea.
El formulario de la pantalla de autenticacin debe tener en cuenta tres cosas:

Debe invocar mediante HTTP POST un recurso denominado: j_security_check

El usuario lo debe enviar en una variable denominada: j_username

La contrasea debe enviarla en una variable denominada: j_password

Por lo dems, la pgina puede mostrar la informacin como quiera. Por ejemplo:

<%@pagelanguage="java"contentType="text/html;charset=ISO88591"
pageEncoding="ISO88591"%>
242

MDULO C Unidad 9: Otros conceptos


<!DOCTYPEhtmlPUBLIC"//W3C//DTDHTML4.01Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<METAhttpequiv="ContentType"content="text/html;charset=ISO
88591">
<TITLE>EjemplodeSeguridad</TITLE>
</HEAD>
<BODY>
<FORMmethod="POST"action="j_security_check">
<TABLE>
<TR>

<TDcolspan="2">Pginadeejemploparalogin:</TD>
</TR>
<TR>
<TD>Usuario:</td>
<TD><INPUTtype="text"name="j_username"></TD>
</TR>
<TR>
<TD>Contrasea:</td>
<TD><INPUTtype="password"name="j_password"></TD>
</TR>
<TR>
<TDcolspan="2"><INPUTtype="submit"value="Login"></TD>
</TR>
</TABLE>
</FORM>
</BODY>
</HTML>
En esta ocasin, cuando el servidor detecte que ha de pedir autenticacin al cliente, en vez de
solicitar al navegador que muestre una ventana devolver nuestra pgina:

Hemos mencionado en varias ocasiones las comunicaciones seguras basadas en el protocolo


HTTPS (HTTP con SSL). Dado que se trata de un tema puramente de configuracin y
administracin de los servidores, y que cada servidor lo hace de una manera distinta no vamos
a detenernos en los detalles en este curso.

243

No obstante, la informacin de cmo se configuran las comunicaciones HTTPS en Apache


Tomcat 7.0.x se encuentra en la siguiente URL:
http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html

9.4

Frameworks de desarrollo web

Uno de los objetivos habituales en el mundo de la informtica es el de mejorar constantemente


la productividad de los desarrolladores. Una manera es mejorando da a da las herramientas
de desarrollo disponibles. Y otra, facilitando el desarrollo a travs de frameworks que
escondan las complejidades y eviten los trabajos repetitivos a los desarrolladores.
Esta ltima es la que comentaremos brevemente a continuacin. Un framework no es ms que
una librera de cdigo junto con una metodologa o forma de trabajar. Su objetivo, no es
reinventar la rueda sino basndose en las tecnologas ya existentes intentar facilitar la vida al
desarrollador.
Durante este curso hemos estudiado las tecnologas, especificaciones y APIs en las que se
basa el desarrollo web Java EE. Los frameworks que comentaremos brevemente a
continuacin no son algo totalmente distinto, sino que basndose en lo que ya hemos
aprendido intentan mejorar la experiencia del desarrollador facilitando el mantenimiento del
cdigo, mejorando los interfaces visuales, evitando trabajos repetitivos, etc pero siempre
por debajo, lleva todo lo aprendido en este curso.
Frameworks hay muchos, simplemente comentaremos cuatro de los ms extendidos en el
mercado laboral actualmente.

9.4.1 JavaServer Faces


JavaServer Faces es una especificacin ms de Java EE. Naci
como un framework separado y con el tiempo se adhesion a las
especificaciones. Siguiendo el estndar Java EE, esta debera ser
la va de evolucin de los programadores web.
Y por qu no hemos estudiado esta opcin entonces en este
curso?
Dos motivos:
1. Se basa en las especificaciones Java Servlet y JavaServer Page. Sin ese conocimiento
adquirido en este curso, no podramos entender JavaServer Faces. Sera como
comenzar la casa por el tejado.
2. Adicionalmente, en el mercado siguen existiendo millones de aplicaciones basadas en
Java Servlets y JavaServer Pages. La necesidad de estos conocimientos sigue
estando ah, es algo que no podemos obviar.
244

MDULO C Unidad 9: Otros conceptos


La idea que persigue JavaServer Faces es definir una serie de conceptos por encima de las
APIs bsicas como son: componentes visuales (controles con lgica avanzada reutilizables a
utilizar en las pginas), beans de gestin (mecanismo que facilita la transmisin de
informacin por el flujo de la aplicacin), validadores (un sistema de control de errores en los
valores de los campos), proveer de un controlador que ya implementa el control del flujo de
la aplicacin mediante un fichero de configuracin, etc
Para profundizar en este framework:
http://docs.oracle.com/javaee/6/tutorial/doc/bnaph.html

9.4.2 Apache Struts


Fue el primer framework de este estilo que
surgi en la Fundacin Apache.
Era muy sencillo de utilizar, y bsicamente aada la posibilidad de definir el flujo de la
aplicacin en un fichero de propiedades que un controlador del propio framework se
encargaba de interpretar. Todas las peticiones pasaban por este controlador y l se
encargaba de direccionar a la pgina que el fichero dijera dependiendo de los valores de
distintos parmetros y/o condiciones.
Tambin aada validadores para facilitar el control de errores de los formularios.
Con la aparicin de JavaServer Faces y otros frameworks como Spring se fue quedando
algo obsoleto y cada vez se usa menos.
Para profundizar en este framework:
http://struts.apache.org/

9.4.3 Spring Source


Junto con JavaServer Faces, es uno de los frameworks
mas extendidos.
Naci como una ayuda mas a la programacin web
pero con el tiempo se fue extendiendo a otras muchas
reas

como

la

programacin

transaccional,

la

persistencia de datos, la programacin de batch, para mviles, etc


Para profundizar en este framework:
http://www.springsource.org/documentation

245

9.4.4 Apache Wicket


Este

es

un

nuevo

framework

junto

con

Struts

tambin

perteneciente a la Fundacin Apache.


Su objetivo es conseguir separar lo mximo posible la presentacin
de la lgica, y definir un modelo de lgica de negocio basado en
POJOs muy sencillo.
No est muy extendido su uso.
Para profundizar en este framework:
http://wicket.apache.org/

246

PARA RECORDAR

Existen dos alternativas, segn las especificaciones Java EE para la gestin de


errores:

Programtica: Toda la gestin se lleva dentro de la aplicacin mediante cdigo


fuente (por ejemplo mediante bloques try/catch).

Declarativa: La gestin se externaliza en configuraciones en el descriptor de


despliegue. Permite controlar:
o Errores HTTP
o Excepciones Java

Una buena gestin de la seguridad debe cubrir los siguientes puntos:

Autenticacin: Asegurarse que un cliente es quien dice ser.

Autorizacin: Asegurarse que un cliente accede solo a los recursos a los que
puede/debe tener acceso y no a otros.

Integridad de datos: Asegurarse que los mensajes llegan sin haber sido
alterados por el camino.

Confidencialidad: Asegurarse que solo las personas autorizadas pueden ver y


acceder a informacin sensible.

No repudio: Asegurarse que quedan evidencias que eviten que un cliente pueda
negar haber realizado una transaccin contra el servidor.

Auditoria: Asegurarse que queda registrado todos los eventos relacionados con
la seguridad para posteriores estudios y anlisis.

Las especificaciones Java EE, nos ofrecen dos aproximaciones distintas al tema de
la seguridad:

Programtica: Define una serie de APIs para que la gestin de la seguridad se


realice directamente desde el cdigo.

Declarativa: Delega en los contenedores Java EE (Servidor de Aplicaciones


Java EE) algunos de los temas relacionados con la gestin de la seguridad.

247

Los mtodos de autenticacin comnmente ms usados son:

BASIC: el servidor pedir al cliente que solicite el usuario y contrasea

FORM: la aplicacin web implementa la pgina de solicitud de usuario y


contrasea, en vez de ser una ventana del navegador.

CLIENT-CERT: requiere que el navegador enve un certificado digital con la


informacin del usuario.

DIGEST: la informacin del usuario y la contrasea van cifradas utilizando


alguno de los algoritmos soportados por ambos lados, cliente y servidor.

Los Frameworks ms extendidos para el desarrollo de aplicaciones web son:

JavaServer Faces es una especificacin ms de Java EE basada en Java


Servlets y en JavaServer Pages (JSP).

Apache Struts fue el primer framework de este estilo que surgi en la


Fundacin Apache.

Spring Source naci como una ayuda mas a la programacin web pero con el
tiempo se fue extendiendo a otras muchas reas como la programacin
transaccional, la persistencia de datos, la programacin de batch, para mviles,
etc

Apache Wicket. Su objetivo es conseguir separar lo mximo posible la


presentacin de la lgica, y definir un modelo de lgica de negocio basado en
POJOs muy sencillo.

248

Potrebbero piacerti anche