Cap 3 Tecnologia - A Java Servlet
Cap 3 Tecnologia - A Java Servlet
1. Introducción
La tecnología Servlet [7] de Java es una poderosa y eficiente solución para crear
contenido dinámico en la Web. Durante los últimos años los Servlets se han convertido
en un bloque fundamental del servidor Java. El poder de los Servlets viene del uso de
Java como plataforma y de la interacción con el contenedor de Servlets. La plataforma
Java proporciona al desarrollador una API robusta, de programación orientada a objetos,
independiente de la plataforma, con tipos estrictos, recolector de basura, y con todas las
características de seguridad de la Máquina Virtual de Java (JVM, Java Virtual
Machine). Complementándolo, el contenedor de Servlets proporciona administración de
ciclos de vida, un único proceso para compartir y administrar recursos de toda la
aplicación, e interacción con el servidor Web. Juntos, consiguen que los Servlets sean la
tecnología más deseable para los desarrolladores de servidores en Java.
Tan pronto como la Web se empezó a usar para proporcionar servicios, los
proveedores de éstos reconocieron la necesidad de contenido dinámico. Los Applets,
uno de los primeros intentos de conseguirlo, se concentran en el uso de la plataforma
del cliente para proporcionar al usuario este contenido dinámico.
29
Capítulo 3 Tecnología Java Servlet
Figura 3.1. Proceso de la petición por parte de una Aplicación Web Java
30
Capítulo 3 Tecnología Java Servlet
Los Servlets son clases Java que dinámicamente procesan peticiones y mandan
respuestas. Las JSPs son documentos de texto que se ejecutan como Servlets pero que
permiten una mayor aproximación a la creación de contenido estático. Aunque se
pueden intercambiar, cada uno tiene sus virtudes. Los Servlets encajan mejor para las
aplicaciones orientadas a servicio (los puntos finales de servicio se implementan como
Servlets) y las funciones de control de una aplicación orientada a presentación, como el
envío de peticiones y el tratamiento de datos que no son de texto. Las JSPs son más
apropiadas para generar marcas de texto como HTML, y XML [4].
Además de los componentes Web y los recursos Web, un módulo Web puede
contener otros archivos:
• Clases de servicio del servidor (beans de bases de datos, carros de la
compra, etc.). A menudo estas clases siguen la arquitectura de
componentes JavaBeans [13].
• Clases del lado del cliente (Applets y clases de servicio).
31
Capítulo 3 Tecnología Java Servlet
32
Capítulo 3 Tecnología Java Servlet
</web-app>
http://servidor:puerto/contexto/alias
33
Capítulo 3 Tecnología Java Servlet
34
Capítulo 3 Tecnología Java Servlet
3 ¿Qué es un Servlet?
Un Servlet es una clase del lenguaje de programación Java usada para extender
las capacidades de los servidores que proporcionan acceso a aplicaciones a través del
modelo de programación petición-respuesta. Aunque los Servlets pueden responder a
cualquier tipo de petición, comúnmente se utilizan para extender las aplicaciones que
sirven los servidores Web. Para esas aplicaciones, la tecnología de Servlet de Java
define unas clases específicas HTTP.
Este ciclo de vida de los Servlets (ver Figura 3.3) es la primera razón por la que
los Servlets (y también las JSP, como se verá más adelante) superan al tradicional CGI.
En contraposición al ciclo de vida de un solo uso de CGI, los Servlets siguen una vida
de tres fases: inicialización, servicio, y destrucción, con la inicialización y la
destrucción ejecutados sólo una vez, y el servicio muchas veces, típicamente.
35
Capítulo 3 Tecnología Java Servlet
La fase de servicio del ciclo de vida del Servlet representa todas las
interacciones con las peticiones hasta que el Servlet es destruido. La interfaz Servlet lo
representa mediante el método service(). Éste método se invoca una vez por petición
y es el responsable de generar las respuestas. La especificación Servlet define que el
método service() tiene dos parámetros: un objeto javax.servlet.ServletRequest
y un javax.servlet.ServletResponse. Estos dos objetos representan la petición del
cliente de contenido dinámico y la respuesta del Servlet al cliente, respectivamente. Por
defecto, un Servlet es multi-hilo, lo que significa que típicamente el contendor sólo
carga una instancia de un Servlet. La inicialización se realiza sólo una vez, y las
posteriores peticiones se manejan concurrentemente por hilos ejecutando este método
service().
La fase de destrucción del ciclo de vida del Servlet representa que el contenedor
va a dejar de usar el Servlet. La interfaz Servlet define el método destroy() que
corresponde con la fase destrucción del ciclo. Cada vez que un Servlet se va a dejar de
usar, el contendor llama al método destroy(), permitiendo que el Servlet finalice y
limpie cualquier recurso que hubiera creado. Usando de forma adecuada las fases de
inicialización, servicio y destrucción del ciclo de vida del Servlet, éste puede utilizar
adecuadamente recursos de la aplicación. Durante la inicialización un Servlet carga todo
lo que necesita para servir peticiones, luego se usan los recursos durante la fase de
servicio y finalmente se limpian en la fase de destrucción.
36
Capítulo 3 Tecnología Java Servlet
Un Servlet necesita ser desplegado para que pueda generar respuestas dinámicas.
El archivo de la clase del Servlet debe ir en el directorio /WEB-INF/classes (o algún
subdirectorio de paquete). Y para que se pueda acceder a él se debe declarar una o más
URLs en web.xml mapeando el nombre del Servlet a una URL:
• Primero se declara el Servlet mediante el elemento servlet que le da un nombre
(que debe ser único entre todos los nombres de los Servlets) y la localización de la
clase Java apropiada, mediante las etiquetas servlet-name y servlet-class
respectivamente.
• Luego se mapea usando el elemento servlet-mapping el nombre definido
anteriormente a una URL o varias mediante las etiquetas servlet-name y url-
pattern respectivamente.
codificación de cada Servlet específico depende, claro, de para lo que se vaya a usar.
Mediante los objetos que reciben éstos métodos se puede acceder a todas las
propiedades de la petición y de la respuesta (sea un Servlet básico, Http, o algún otro
tipo de subclase) de una forma sencilla. Por ejemplo, para enviar información al cliente,
mediante el objeto HttpServletResponse se puede obtener, gracias al método
getWriter() o getOutputStream(), un flujo de salida para escribir contenido en la
respuesta al cliente. Estos dos métodos devuelven los objetos para enviar texto o
contenido binario al cliente, respectivamente. Y mediante el objeto
HttpServletRequest se puede acceder a las cabeceras, parámetros y archivos enviados
por el cliente; como por ejemplo, mediante el método getParameter(String
NombreDelParametro) se accede al valor String del parámetro requerido del
formulario enviado en la petición.
Es importante que la Aplicación Web sea portable, ya que puede que se ejecute
en distintos contenedores, o incluso desde un archivo WAR, así que se deben evitar
referencias absolutas a recursos, y acceder a ellos mediante el método anterior, u otros
similares del objeto ServletContext para conseguir que sea realmente portable.
38
Capítulo 3 Tecnología Java Servlet
Así, de la clase escuchadora que se desee usar, sólo deberán implementarse los
métodos según los eventos que se quieran manejar, y declarar la clase en el archivo de
despliegue de la Aplicación Web.
39
Capítulo 3 Tecnología Java Servlet
aunque la que se ha utilizado en este proyecto es la versión 2.0, ya que era la única
disponible cuando se comenzó su desarrollo. De hecho, el contenedor Tomcat [51] aún
no tiene una versión que soporte la nueva versión de JSP; la versión de Tomcat 6.0 que
debe soportarlo está aún en desarrollo, estando sólo disponible su versión beta.
El ciclo de vida, aunque los nombres son distintos, se corresponde con el del
Servlet, permitiendo a la JSP cargar recursos, proporcionar servicio a peticiones de
múltiples clientes y destruir los recursos cargados cuando la JSP quede fuera de
servicio.
40
Capítulo 3 Tecnología Java Servlet
Codificar una JSP puede ser tan fácil como poner el código HTML de una
página Web estática en un archivo que tenga extensión “jsp”. Comparado con tener que
estar usando los métodos de la familia print() continuamente, la aproximación de las
JSP es evidentemente más fácil. Es por esta razón por la que las JSP simples se
consideran un método rápido para crear Servlets productores de texto. Desplegar una
JSP también es más simple; una Aplicación Web automáticamente despliega cualquier
JSP a una URL igual que el nombre de la JSP.
Los datos plantilla están formados por cualquier texto plano, que no sea un
elemento; así, cualquier código HTML que tenga la JSP, toda la información de la
estructura, contenido estático, etc. forma parte de los datos plantilla, y se envían
directamente al cliente. Los datos plantilla no cambian. Por otro lado, los elementos no
se envían directamente al cliente. Un elemento se interpreta por parte del contendor JSP
y define que se debe tomar una acción especial para generar una respuesta. Los
elementos son los que hacen que las JSP sean dinámicas. Éstos se dividen a su vez en
tres categorías diferentes: elementos de script, directivas y acciones.
4.4.1.1 Scripts
La forma más simple de hacer una JSP dinámica es incrustar trozos de código
Java directamente entre bloques de datos plantilla a través del uso de elementos de
script. Las JSPs no limitan los elementos de script a código Java, pero la especificación
sólo habla de Java como lenguaje de script, y todos los contenedores deben soportar por
defecto Java. Hay tres tipos de elementos de scripts permitidos en las JSPs: scriptlets,
expresiones y declaraciones.
41
Capítulo 3 Tecnología Java Servlet
Hay que tener cuidado al utilizar los scriptlets y las declaraciones, ya que no
tienen seguridad de hilo. Las expresiones no tienen este problema.
4.4.1.2 Directivas
Las directivas son mensajes al contenedor JSP. No mandan nada al cliente, pero
se usan para definir atributos de la página, qué bibliotecas de etiquetas personalizadas
incluir y qué otras páginas incluir. Usan la siguiente sintaxis,
42
Capítulo 3 Tecnología Java Servlet
• <%@ include%> y <jsp:include/>: Esta directiva se usa para incluir texto y/o
código en tiempo de traducción de la JSP. Siempre sigue la misma sintaxis, <%@
include file="URLrelativa" %>, con la URL relativa del archivo a insertar. Los
archivos a incluir deben formar parte de la Aplicación Web. Como tiene lugar en tiempo
de traducción, es equivalente a incluir el código fuente directamente en la JSP antes de
su compilación y no da lugar a pérdida de rendimiento en su ejecución. Mediante esta
directiva se puede incluir el mismo trozo de código repetitivo colocado en un archivo a
parte en muchas páginas.
Para incluir cosas que no sea en tiempo de ejecución JSP también define la
acción jsp:include (las acciones se verán posteriormente) Esta acción es similar a la
directiva, pero tiene lugar durante la ejecución. Aunque no es eficiente, la acción se
asegura de que se incluye la última versión del archivo. Esto puede ser útil si el archivo
a incluir cambia a menudo.
• <%@ taglib %>: Esta directiva informa al contenedor sobre qué parte de las marcas
de la página debe ser considerada como código personalizado (acciones personalizadas,
se verán posteriormente) y dónde encontrar ese código. Su sintaxis es siempre la misma,
<%@ taglib uri="uri" prefix="prefijoDeLaEtiqueta" %>, donde uri representa
una localización que entiende el contenedor y prefix informa de cuáles de las marcas
son acciones personalizadas asociadas a esa localización.
Las acciones proporcionan un método conveniente para enlazar código con unas
simples marcas que aparecen en una JSP. La funcionalidad es idéntica a los elementos
de script pero con la ventaja de abstraer completamente cualquier código (que iría en el
script) que normalmente se mezclaría con el resto de la JSP. De esta forma ayudan a
facilitar el mantenimiento y la eficiencia de una JSP. Hay dos tipos de acciones
disponibles para una JSP: estándar y personalizadas, aunque todas siguen la misma
sintaxis, <prefijo:elemento {atributo="valor"}* />, que es compatible con una
etiqueta XML [4]. Las acciones estándar están definidas en la especificación JSP y están
disponibles para su uso con cualquier contenedor JSP. Las acciones personalizadas es
un mecanismo definido en la especificación JSP para mejorarlas permitiendo a los
desarrolladores de JSP crear sus propias acciones.
Los contenedores JSP deben soportar dos tipos de sintaxis: normal y compatible
con XML [4]. La normal está pensada para ser fácil para el autor. La compatible con
XML toma la normal y la modifica para que sea conforme con XML, y está pensada
para que sea más fácil su uso con herramientas de desarrollo. La compatible con XML
se introdujo en la versión 1.2 de JSP, y desde el punto de vista del desarrollador es
mucho más engorrosa y no merece la pena, ya que es más compleja. La versión 2.0 de
JSP remedió algo el problema proporcionando una sintaxis XML más flexible, aunque
43
Capítulo 3 Tecnología Java Servlet
sigue siendo para el desarrollador mucho más complejo y tedioso hacer una JSP
compatible con XML.
Las directivas son la forma más fácil de configurar una JSP. Pero tienen el
problema de que se deben especificar para todas las JSP de la Aplicación. Para
simplificarlo, está disponible el elemento jsp-config para usarlo en web.xml. Hay dos
subelementos: taglib y jsp-property-group. El primer elemento se usa para
configurar una biblioteca de etiquetas personalizadas para su uso en una JSP. La
segunda permite la configuración de forma similar a las directivas, pero se puede aplicar
a un grupo de JSP.
JSP tiene disponibles una serie de objetos implícitos que le permiten fácilmente
manipular la petición, la respuesta o la sesión. Los siguientes objetos están siempre
disponibles para usar en elementos de script ya que se declaran automáticamente en una
JSP y tienen su equivalente en el Servlet:
• config: Al igual que con los Servlets, se pueden declarar parámetros iniciales a las
JSPs mediante el descriptor de despliegue de la Aplicación Web, y acceder a ellos
mediante este objeto, instancia de javax.servlet.ServletConfig.
• request: Representa la petición del cliente, y hace referencia al objeto pasado al
método del Servlet que sirve esa petición. Es una instancia de
javax.servlet.http.HttpServletRequest.
• response: Representa la respuesta para el cliente y hace referencia al objeto pasado
al método del Servlet que debe enviar esa respuesta. Es una instancia de
javax.servlet.http.HttpServletResponse.
• session: Es un objeto que representa el contexto de la sesión de cada cliente. Es una
instancia de javax.servlet.http.HttpSession, y es equivalente al objeto devuelto
por la llamada a HttpServletRequest.getSession().
• application: Representa la visión del Servlet de la Aplicación Web. Es una
instancia de javax.servlet.ServletContext y es equivalente al objeto devuelto por
la llamada al método ServletConfig.getServletContext().
44
Capítulo 3 Tecnología Java Servlet
Las excepciones se pueden controlar en los Servlets y las JSPs mediante el uso
de las sentencias Java try-catch-finally libremente. Pero además, las JSP pueden
usar la directiva page para especificar una página a la que pasar las excepciones que no
sean capturadas. Mediante su atributo errorPage se puede asignar una URL que puede
representar una JSP o un Servlet especialmente diseñado para ser una página de error.
Una JSP diseñada para ser una página de error puede establecer el valor del atributo
isErrorPage de la directiva page a “true”; con esto se consigue que la variable de
script exception esté automáticamente disponible para representar a la excepción
pasada.
Así se puede asegurar que las trazas de error y los mensajes específicos nunca
alcanzarán al usuario. La JSP diseñada para ser una página de error se puede realizar de
forma que se adecue al resto de la Aplicación Web y sea más “agradable” al usuario.
Para controlar las excepciones de toda la Aplicación Web se debe hacer uso del
archivo web.xml, modificando el comportamiento del manejador de excepciones por
defecto de la Aplicación Web. Se definen las páginas de error para toda la Aplicación en
el descriptor de despliegue de la aplicación, web.xml, mediante el elemento error-
page, definiendo manejadores de error en función de la excepción lanzada o el código
de error HTTP producido por la respuesta. El elemento error-page contiene
subelementos que especifican la URL relativa de la página de error y o bien el código
HTTP de error de respuesta o bien el tipo de Throwable que está asociado con la página
de error (una clase Java cualificada).
45
Capítulo 3 Tecnología Java Servlet
sintaxis clara y un lenguaje especialmente diseñado para JSP. Además, funciona bien
con las JSPs en sintaxis XML, ya que el JSP EL no requiere el uso de caracteres que
forman parte de las marcas XML.
Además, el JSP EL se puede usar en cualquier lugar de una JSP. Esto hace que
sea una alternativa simple y poderosa a los elementos de script.
El JSP EL está diseñador para ser simple, robusto, y con mínimo impacto con las
versiones anteriores. El EL maneja expresiones y literales. Las expresiones siempre
están encerradas en los caracteres ${ }. Por ejemplo:
Los valores que no empiezan con “${” se tratan como un literal. El valor del
literal se convierte al tipo esperado dependiendo de la entrada en el TLD (Tag Library
Descriptor, Descriptor de la Biblioteca de Etiquetas, descrito posteriormente) de la
etiqueta:
En los casos en los que el valor del literal contiene los caracteres “${”, se deben
poner los caracteres de escape “$\{”.
6.1.1 Atributos
46
Capítulo 3 Tecnología Java Servlet
6.1.2 Literales
El EL define los literales booleanos, long (como en Java), float (como en Java),
String (como en Java), y null (como en Java).
6.1.3 Operadores
Usar las bibliotecas estándar de etiquetas es simple, sólo hay que importarlas en
las páginas JSP mediante la directiva taglib. Por ejemplo, para importar la biblioteca
JSTL “core” en una página, se debe incluir la línea siguiente al comienzo de la página
JSP:
A pesar de que la funcionalidad que realiza JSTL no es nueva, y las acciones que
realizan se pueden hacer mediante elementos de scripts y expresiones, su uso es muy
aconsejable. JSTL es estándar, y es una buena implementación de muchas funciones
útiles. Al ser estándar no se tienen que aprender nuevas formas de realizar dichas
funciones o diseñar nuevas etiquetas que las realicen.
47
Capítulo 3 Tecnología Java Servlet
Colección de etiquetas para formatear texto diseñadas para sitios Web con
internacionalización (i18n), implementación de una de las soluciones más comunes
usadas en i18n.
Proporciona una forma flexible de manipular XML. Puede ser muy útil para
crear XML para tecnologías como Servicios Web. Proporciona algunas funciones de
manipulación XML y el equivalente XML de las etiquetas “core” y condicionales de
JSTL. Se dividen en tres grupos:
• Etiquetas XML core: Etiquetas equivalentes a las JSTL “core”, pero con soporte
para EL y XPath [15].
• Etiquetas de Control de Flujo: Implementación XPath de las etiquetas choose,
when, otherwise, if y forEach.
• Etiquetas de Transformación: Proporciona una forma de aplicar transformaciones
XSLT [16] a contenido XML.
Proporcionan una interfaz simple para ejecutar peticiones SQL a una base de
datos a través de una JSP.
También las etiquetas personalizadas son muy fáciles de usar tanto por
programadores como por no programadores. Incluso un diseñador HTML sin
experiencia con Java puede fácilmente utilizarlas. Por eso las etiquetas personalizadas
49
Capítulo 3 Tecnología Java Servlet
son una buena forma de abstraer una lógica compleja en una capa de presentación
sencilla en lenguaje HTML o XML.
Con la versión de JSP 2.0 se introdujo una nueva forma de escribir etiquetas
personalizadas, que permite que se escriban utilizando código Java (como siempre) o
como una JSP (la forma nueva), y que son más simples que las antiguas etiquetas
personalizadas. Aunque ambos tipos se pueden combinar de cualquier manera en la JSP,
las antiguas y las nuevas.
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<tlib-version>1.0</tlib-version>
<short-name>Util TLD</short-name>
<jsp-version>2.0</jsp-version>
<uri>http://www.QTI.us.es/util</uri>
<tag>
<name>adminMail</name>
<tag-class>utilidades.etiquetas.util.AdminMailTag</tag-class>
<body-content>empty</body-content>
</tag>
<tag>
<name>reqURI</name>
<tag-class>utilidades.etiquetas.util.RequestedURITag</tag-class>
<body-content>empty</body-content>
</tag>
<tag>
<name>logger</name>
<tag-class>utilidades.etiquetas.util.logging.LoggerTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>nivel</name>
<required>true</required>
50
Capítulo 3 Tecnología Java Servlet
<type>java.lang.String</type>
</attribute>
<attribute>
<name>mensaje</name>
<required>true</required>
<type>java.lang.String</type>
</attribute>
</tag>
</taglib>
No es más que una colección de elementos tag. Así, para cada una se informa de
su nombre (que debe ser único dentro de las etiquetas de la biblioteca), la clase Java que
maneja la llamada (un nombre completo de una clase Java existente), el tipo de código
que se permite dentro del cuerpo de la etiqueta (vacío, JSP, sin scripts o a interpretar por
la etiqueta), y una descripción de los atributos de la etiqueta, si los tiene.
Una forma más adecuada de realizar la referencia es definir una URI abstracta
para toda la aplicación, y hacerla corresponder a esa TLD. Esta correspondencia se
realiza en el descriptor de despliegue de la Aplicación Web, web.xml. Así, una JSP que
quiera utilizarla sólo tiene que referenciar esta URI abstracta, que se encarga de resolver
la Aplicación Web. No hay ningún problema si se cambia de sitio la JSP, todas las JSPs
usan la misma URI, y si se cambia la posición de la TLD sólo hay que modificar el
descriptor de despliegue de la Aplicación Web. Aunque para ahorra aún más trabajo, se
puede añadir a la propia TLD, antes de las declaraciones de las etiquetas, una entrada
<uri>, donde se define una URI abstracta para la TLD. Así, sólo haciendo referencia a
estas URIs y poniendo el archivo TLD en el directorio /WEB-INF o algún subdirectorio
de éste, o, si está en un JAR, dentro del directorio de JARs en el directorio /META-INF
(ver especificación de los archivos JAR [42]), ya estará disponible para las JSPs con
sólo referenciar su URI abstracta.
51
Capítulo 3 Tecnología Java Servlet
Con la versión de JSP 2.0 se introdujeron los archivos .tag, que permiten
prescindir de Java para hacer etiquetas personalizadas. Estas etiquetas permiten que se
escriban en JSP, permitiendo que el autor no tenga que saber programar Java. Así, estas
etiquetas son más útiles para las que deben contener muchos datos de salida para la JSP,
ya que no hace falta poner multitud de out.print(...).
Estas etiquetas son las que existían antes de la versión 2.0 de JSP, y aún están
disponibles. Hay tres tipos de etiquetas: “básicas”, de “iteración”, y de “cuerpo”, cada
52
Capítulo 3 Tecnología Java Servlet
9 Filtros
Los Filtros son componentes que se sitúan entre la petición y el punto final de
esa petición (recurso dinámico o estático de cualquier tipo, existente o no). Un Filtro es
capaz de:
• Leer la petición antes de llegar al punto final.
• Envolver los datos de la petición antes de pasarlos.
• Envolver los datos de la respuesta antes de devolverla.
• Manipular los datos de respuesta antes de devolverlos.
• Devolver errores al cliente.
• Enviar la petición a otro lugar e ignorar la URL original.
• Generar su propia respuesta antes de enviarla al cliente.
Figura 3.7. Paso de la petición por los Filtros hasta el punto final
53
Capítulo 3 Tecnología Java Servlet
Una vez compilado el código, antes de poder usarlo, el Filtro debe ser
desplegado en la Aplicación Web. Su despliegue es similar al de un Servlet, pero
usando el elemento filter para declarar el filtro, y con los subelementos filter-name
para el nombre del filtro, y filter-class para indicar la clase Java del Filtro. Y el
mapeo se realiza mediante el elemento filter-mapping, y con los subelementos
filter-name se referencia un Filtro ya declarado, y con url-pattern se especifican
las URL [20] de las peticiones que el Filtro “interferirá”. Así se configura cada Filtro
para que actúe siempre que la URL requerida sea la definida, pudiéndose utilizar
caracteres comodines para que actúe con más de un destino, pudiendo quedar una
configuración como se ve en la Figura 3.8 de tres Filtros (Fx) con tres destinos (Dx).
54
Capítulo 3 Tecnología Java Servlet
9.4 Envoltorios
Los Filtros tienen la capacidad de envolver una petición y/o una respuesta,
consiguiendo así encapsular una petición o una respuesta en otra (personalizada).
Personalizando un envoltorio se consigue que la petición o la respuesta no se comporte
de forma normal. Los envoltorios no son específicos de los Filtros, pero junto con ellos
se consigue un gran beneficio.
Un envoltorio es solo una implementación del objeto que está siendo envuelto.
Por ejemplo, la API Servlet proporciona las clases ServletRequestWrapper y
55
Capítulo 3 Tecnología Java Servlet
Para mantener el estado mediante las cookies, la API Servlet abstrae los detalles
técnicos de forma que no se tenga que preocupar el programador para un uso normal.
Aún así, contiene métodos para acceder a ellas y modificarlas según convenga.
Cuando las cookies fallan, se utiliza la reescritura de URL que permite llevar el
seguimiento de la sesión con HTTP, reescribiendo la URL original para que tenga
también el identificador de la sesión. Se puede hacer de distintas formas, siempre que el
servidor entienda la nueva URL, por ejemplo, añadiendo nuevos parámetros. Lo malo es
que se deben reescribir siempre todas las URLs y diferentes para cada usuario.
Sus métodos procesan una petición HTTP [52] que se ajuste al RFC 1867,
“Form-based File Upload in HTML” [21]. Es decir, si se envía una petición HTTP
usando el método POST, y con un contenido de tipo “multipart/form-data”, entonces los
métodos de FileUpload pueden procesar la petición y dejar disponible los resultados de
forma que sean fáciles de utilizar por la aplicación que llamó a esos métodos.
56
Capítulo 3 Tecnología Java Servlet
Una petición de subida de archivo contiene una lista ordenada de objetos que se
codifican de acuerdo a la RFC 1867, “Form-based File Upload in HTML”. FileUpload
procesa la petición y proporciona a la aplicación una lista de objetos subidos
individuales. Cada uno de estos objetos implementa la interfaz FileItem, a pesar de su
implementación subyacente.
// Procesa la petición
List /* FileItem */ items = upload.parseRequest(request);
Siempre se puede pasar sin configurar alguno de esos aspectos, que se quedarán
a sus valores por defecto:
57
Capítulo 3 Tecnología Java Servlet
if (item.isFormField()) {
// Si es un campo de formulario
String name = item.getFieldName();
String value = item.getString();
...
} else {
// Si es un archivo subido
String fieldName = item.getFieldName();
String fileName = item.getName();
String contentType = item.getContentType();
boolean isInMemory = item.isInMemory();
long sizeInBytes = item.getSize();
...
if (writeToFile) {
File uploadedFile = new File(...);
item.write(uploadedFile);
} else {
InputStream uploadedStream = item.getInputStream();
...
uploadedStream.close();
}
}
}
58
Capítulo 3 Tecnología Java Servlet
12. Conclusiones
La tecnología Servlet de Java permite añadir contenido dinámico a un servidor
usando la plataforma Java. Generalmente, el contenido generado es HTML [49], pero
puede ser otro tipo de datos como XML. Los Servlets son los homólogos Java de las
tecnologías de contenido Web dinámico no Java, como CGI y ASP .NET.
También, las JSPs permiten escribir Servlets productores de texto, sobre todo
productores de páginas Web HTML, de forma fácil y sencilla, igual que se haría con
una página HTML normal, pero incluyendo cualquier código Java que se quiera en ella.
A parte de los Servlets propiamente dichos y las JSPs, la tecnología incluye una
serie de características que expanden su funcionalidad. Por ejemplo, mediante los filtros
se puede realizar modificaciones sobre las peticiones, independientemente del Servlet
destino, modificando el comportamiento de la petición o la respuesta aplicándoles
envoltorios; también se definen escuchadores de eventos, que permiten crear clases que
respondan a determinados “eventos” ante los que se quiera reaccionar.
59
Capítulo 3 Tecnología Java Servlet
Las JSPs con código Java directamente en ellas se pueden volver difíciles de
mantener y depurar, pero, gracias a la utilización de la biblioteca estándar de etiquetas,
las etiquetas personalizadas y el lenguaje de expresión de JSP, se puede conseguir que
una JSP que se genere dinámicamente tenga la apariencia de casi una página HTML
normal, o, al menos, un documento XML. Así, se tendrá una página mucho más fácil de
mantener, que incluso podrá ser creada por un desarrollador de páginas Web estáticas
con muy poco entrenamiento, dejando la creación de la lógica y las etiquetas a
desarrolladores Java, o JSP. De esta manera, se puede desarrollar una Aplicación Web
que siga el patrón de diseño “Modelo Vista Controlador”, permitiendo una separación
entre la lógica de negocio (implementada mediante Servlets, etiquetas personalizadas, o
JavaBeans [13], por ejemplo) y la presentación (implementada mediante JSPs).
60