Tutorial J2EE Servlets #Hicham Qaissi#
2
Contenido 0. Qué es un Servlet: ...................................................................................................................................................... 4
1. Ventajas: .................................................................................................................................................................... 4
2. La API Servlet: ............................................................................................................................................................ 4
3. Estructura y funcionamiento interno: ........................................................................................................................ 4
4. Implementación de un Servlet. .................................................................................................................................. 5
4.1 Modelos de implementación. ............................................................................................................................. 5
4.2 La clase HttpServlet ............................................................................................................................................. 6
4.3 Inicialización y destrucción de un Servlet: La interfaz Servlet ............................................................................. 7
4.3.1. Inicialización, método init(…) ..................................................................................................................... 7
4.3.2. En servicio, método service(…) ................................................................................................................... 7
4.3.3. Destrucción, método destroy() ................................................................................................................... 7
5. Llamada a un Servlet .................................................................................................................................................. 8
5.1. Llamada del método doGet(…) ........................................................................................................................... 8
5.2. Llamada del método doPost(…) ......................................................................................................................... 8
6. Configuración del Servlet: La interfaz ServletConfig ................................................................................................. 9
6.2. web.xml .............................................................................................................................................................. 9
6.2 Inicialización de un Servlet: redefinición del método init() ................................................................................. 9
6.2.1. Métodos de la interfaz ServletConfig ....................................................................................................... 10
6.2.2. Ejemplo de uso de ServletConfig en el método init() ............................................................................... 10
7. El contexto de aplicación: La interfaz ServletContext .............................................................................................. 10
7.1. Obtención de un objeto ServletContext ........................................................................................................... 11
7.2. Parámetros de la aplicación Web. .................................................................................................................... 11
7.2.1. Configuración de los parámetros en web.xml .......................................................................................... 11
7.2.2. Métodos para recuperación de los parámetros en web.xml .................................................................... 11
7.3. Atributos del context de la aplicación Web ................................................................................................ 11
7.3.1. Métodos de gestión de los atributos del contexto de aplicación ............................................................. 11
8. Tratamiento de las peticiones: Las interfaces ServletRequest y HttpServletRequest .............................................. 11
8.1. Recuperación de los parámetros transmitidos en la petición: ......................................................................... 12
8.2. Atributos del context de petición ..................................................................................................................... 12
8.3 Gestión del flujo de entrada .............................................................................................................................. 12
8.4 Recuperación de información sobre el URL de la petición ................................................................................ 12
8.5 Recuperación de información del cliente .......................................................................................................... 13
8.6 Recuperación de información sobre el servidor ................................................................................................ 13
8.7 Recuperación de información en el encabezado HTTP ..................................................................................... 13
9. Tratamiento de las rspuestas ServletResponse y HttpServletResponse .................................................................. 13
9.1 Declaración del tamaño y tipo del contenido de respuesta .............................................................................. 13
9.2 Introducir información en el encabezado HTTP ................................................................................................ 14
9.3 Gestión del flujo de salida ................................................................................................................................. 14
9.4 Gestión de la puesta en memoria intermedia ................................................................................................... 14
9.5 Codificación de URL ........................................................................................................................................... 15
9.6 Envío de errores y de estados HTTP y redirección de URL ................................................................................ 15
10. Sincronización delos procesos: La interfaz SingleThreadModel ............................................................................. 16
10.1. Sin la implementación de la interfaz SingleThreadModel .............................................................................. 16
10.2. Con la implementación de la interfaz SingleThreadModel ............................................................................. 16
11. Los filtros: la interfaz Filter ..................................................................................................................................... 17
11.1. Principios de utilización .................................................................................................................................. 17
11.2. Implementación: La interfaz Filter ................................................................................................................. 18
11.2.1. La interfaz Filter ...................................................................................................................................... 18
11.2.2. La interfaz Filterconfig ............................................................................................................................ 18
11.2.3. La interfaz FilterChain ............................................................................................................................. 19
12. Los eventos de una aplicación Web ....................................................................................................................... 20
12.1. principios de funcionamiento y utilización ..................................................................................................... 20
11.2. Los eventos de contexto de la aplicación Web. ............................................................................................. 20
11.2.1. Notificación de la creación/destrucción del contexto de la aplicación Web: la interfaz
ServletContextListener ....................................................................................................................................... 20
12.2.3. Notificación de adición/modificación/supresión de atributos de contexto de la aplicación Web: la
interfaz ServletContextAttributeListener ........................................................................................................... 21
12.3. Los eventos de sesión HTTP ........................................................................................................................... 21
12.3.1. Notificación dela creación/destrucción de una sesión HTTP: La interfaz HttpSessionListener .............. 21
12.3.2. Notificación de la activación/desactivación de una sesión HTTP: la interfaz
HttpSessionActivationListener ........................................................................................................................... 21
Tutorial J2EE Servlets #Hicham Qaissi#
3
12.3.3. Notificación de la adición/modificación/supresión de atributos de una sesión HTTP: la interfaz
HttpSessionAttributeListener ............................................................................................................................. 21
12.4. Despliegue ...................................................................................................................................................... 22
12.5. Ejemplo de puesta en marcha. ....................................................................................................................... 22
13. Mantener el estado de los clientes ........................................................................................................................ 22
13.1. Las Cookies: la clase Cookie. ........................................................................................................................... 22
13.1.1. ¿Qué es? ................................................................................................................................................. 22
13.1.2. Estructura ............................................................................................................................................... 22
13.1.3. Trabajar con las cookies: la clase Cookie. ............................................................................................... 23
13.1.4. Enviar cookies en la respuesta HTTP ...................................................................................................... 23
13.1.5. Recuperación de cookies en la petición HTTP ........................................................................................ 23
13.1.6. Suprimir una cookie ................................................................................................................................ 24
13.2. Las sesiones: La interfaz HttpSession ............................................................................................................. 24
13.2.1. ¿Qué es? ................................................................................................................................................. 24
13.2.2. ¿Cómo obtener una sesión? ................................................................................................................... 24
13.2.3. Trabajar con una session: La interfaz HttpSession ................................................................................. 24
13.3. Las sesiones y la reescritura de URL ..................................................................................................... 25
14. Colaboración entre Servlets: La interfaz RequestDispacher .................................................................................. 27
14.1. ¿Qué es? ........................................................................................................................................................ 27
14.2. Obtener un objeto RequestDispacher ............................................................................................................ 27
Tutorial J2EE Servlets #Hicham Qaissi#
4
0. Qué es un Servlet: Componente web concebido en una clase Java que existe en una aplicación Web y cuya
utilización está gestionada por un contenedor Web. Interacciona con un cliente Web mediante
HTTP a través de un mecanismo petición �� respuesta. Permite extender las posibilidades de
un servidor Web, aportando la posibilidad de generar contenido dinámico en respuesta a las
peticiones de los clientes. En una arquitectura Modelo-Vista-Controlador, un Servlet juega el
rol de controlador.
1. Ventajas:
• Portable y evolutivo al estar escrito en Java y solo necesita un contenedor para su
ejecución.
• Potente, porque está cargado en memoria desde su primera llamada o desde el inicio
del servidor de aplicación.
• Disponible porque se ejecuta en un contexto multitarea. Se crea una sola instancia que
crea una hebra para cada petición cliente.
2. La API Servlet: La API Servlet proporciona un cierto número de clases y de interfaces que permiten el
desarrollo de Servlets, así como su despliegue y su puesta en marcha en el contenedor Web. La
API Servlet está contenida en dos paquetes: javax.servlet y javax.servlet.http.
3. Estructura y funcionamiento interno:
Cuando un cliente llama a un Servlet emitiendo una petición HTTP, se llama al método service
sobre el contenedor Web que recibe dos parámetros de tipo javax.servlet.ServletRequest y
javax.servlet.ServletResponse respectivamente que permiten procesar las peticiones emitidas
por los clientes y las respuestas devueltas a los mismos.
Un objeto del tipo javax.servlet.ServletRequest proporciona métodos que permiten recuperar
o insertar datos en la petición, y métodos que permiten sacar las metainformaciones
contenidas en la petición (información del cliente, información del servidor, tipo y tamaño del
contenido).
Un objeto del tipo javax.servlet.ServletResponse proporciona métodos que permiten obtener
objetos con el fin de insertar datos (texto o binario) en la respuesta que se reenvía al cliente,
así como métodos que permiten actuar sobre el buffer de datos.
public void service(ServletRequest req, ServletResponse res)
public void service(HttpServletRequest req, HttpServletResponse res)
public void doXXX(HttpServletRequest req, HttpServletResponse res)
Servlet
Petición HTTP
Respuesta HTTP
Tutorial J2EE Servlets #Hicham Qaissi#
5
El único proceso realizado por el método service(…) es la invocación del propio método
sobrecargado, que toma dos parámetros de tipo javax.servlet.HttpServletRequest y
javax.servlet.HttpServletResponse respectivamente.
La interfaz javax.servlet.HttpServletRequest hereda de la interfaz
javax.servlet.ServletRequest y la interfaz javax.servlet.HttpServletResponse hereda de
javax.servlet.ServletResponse.
Los objetos javax.servlet.HttpServletRequest y javax.servlet.HttpServletResponse
proporcionan métodos, además de los ya heredados, específicos del protocolo HTTP
(encabezado, cookies, errores, sesión, autenticación, etc.).
Además, el método service(…) invoca por defecto al método correspondiente al método HTTP
utilizado por el cliente (principalmente doGet(…), doPost(…), doPut(…), doDelete(…)),
transmitiéndole los parámetros de tipo javax.servlet.HttpServletRequest y
javax.servlet.HttpServletResponse. El desarrollador será quien se encarga de implementar
entonces los procesos sobre la respuesta del método doXXX(…) o aquellos que utilicen la
misma.
La diferencia entre doGet(…) y doPost(…) es que el primero se ejecuta cuando se llama al
Servlet directamente y pasar le información ligera tipo
(MiApp/MiServlet?param1=val1¶m2=val2) y el segundo es llamado cuando se intentan
pasar parámetros con un formulario (Información pesada…).
4. Implementación de un Servlet.
4.1 Modelos de implementación.
Implementar un Servlet consiste en escribir una clase que extiende la clase abstracta
javax.servlet.http.HttpServlet, que proporciona un modelo de base para la creación de
Servlets HTTP.
Con el fin de interactuar con los clientes es necesario redefinir el método service(…) (que es el
que se ejecuta siempre), en cuyo caso se interceptan todos los tipos de peticiones HTTP
aunque sin hacer distinción alguna (modelo 1), o bien uno o varios métodos doXXX(…), en
correspondencia con los tipos de métodos HTTP que pueden ser emitidos por los clientes para
interactuar con el Servlet.
Por lo general, redefinimos los métodos doGet(…) y doPost(…) (modelo 2), porque los clientes
normalmente emiten peticiones GET (Solicitud de un recurso) y POST (envío de datos que
tienen un recurso como destino).
La práctica mas correcta es rederfinir el método service(…) y allí llamar a otro método
processRequest(req, res) que implementamos nosotros y que se encarga de procesar la
petición y la lógica de negocio.
Tutorial J2EE Servlets #Hicham Qaissi#
6
4.2 La clase HttpServlet
La clase javax.servlet.http.HttpServlet extiende de javax.servlet.GenericServlet que
implementa las interfaces javax.servlet.Servlet y javax.servlet.ServletConfig que le
proporcionan de este modo una estructura elaborada para las necesidades de las aplicaciones
Web.
Lista de los principales métodos:
El método service(…) es llamado por defecto por el contenedor Web, sea cual sea el método
HTTP de la petición del cliente. Se ocupa de llamar al método correspondiente para realizar los
procesos. Este método puede, por tanto, ser redefinido con el fin de realizar un proceso
global de todos los tipos de peticiones.
protected void service(HttpServletRequest req, Http ServletResponse res) throws ServletException, IOException;
La clase proporciona métodos que corresponden a los distintos métodos HTTP que, según las
necesidades, se redefinirán en las subclases. Todos esos métodos poseen dos parámetros del
tipo javax.servlet.http.HttpServletResquest y javax.servlet.http.HttpServletResponse. Por
defecto, cada uno de esos métodos es llamado con el método service(…) si éste no ha sido
redefinido. El método service() se ejecuta siempre en cualquier petición.
protected void doDelete(HttpServletRequest req, Htt pServletResponse res)
throws ServletException, IOException;
protected void doGet(HttpServletRequest req, HttpSe rvletResponse res) throws
ServletException, IOException;
protected void doHead(HttpServletRequest req, HttpS ervletResponse res) throws ServletException, IOException;
protected void doOptions(HttpServletRequest req, Ht tpServletResponse res)
throws ServletException, IOException;
protected void doPost(HttpServletRequest req, HttpS ervletResponse res) throws
ServletException, IOException;
protected void doPut(HttpServletRequest req, HttpSe rvletResponse res) throws ServletException, IOException;
protected void doTrace(HttpServletRequest req, Http ServletResponse res) throws ServletException, IOException;
Tutorial J2EE Servlets #Hicham Qaissi#
7
4.3 Inicialización y destrucción de un Servlet: La interfaz Servlet
La interfaz javax.servlet.Servlet (implementada por javax.servlet.GenericServlet de la cual
hereda javax.servlet.http.HttpServlet) proporciona los métodos correspondientes al ciclo de
vida del Servlet: inicialización, en servicio (tratamiento de las peticiones), destrucción.
4.3.1. Inicialización, método init(…)
Una vez que el contenedor Web ha cargado (instanciado) el Servlet, ejecuta el método init(…)
del Servlet correspondiente a su fase de inicialización. Por defecto, este método no hace
absolutamente nada, se aconseja redefinirlo en el código de los Servlets, para cambiar
recursos utilizados en el resto de funcionamiento del Servlet (Conexiones JDBC, archivos
properties…), o bien para recuperar parámetros de inicialización asignados en el descriptor
de despliegue (web.xml) de la aplicación Web por medio del objeto ServletConfig pasado
como parámetro.
Public void init(ServletConfig config) throws Servl etException;
Si redefinimos este método, debemos añadirle la instrucción super.init(config); que permite
almacenar la referencia del objeto ServletConfig para futuras utilizaciones. Es aún mas simple
redefinir en nuestra clase de Servlet el método init() sin parámetros de la clase
java.servlet.GenericServlet. El contenedor Web interrumpe el ciclo de vida del Servlet (no lo
pone en servicio) si el método init(…) lanza una ServletException o si no devuelve el control en
un tiempo definido por el servicio Web.
4.3.2. En servicio, método service(…)
Una vez se ha realizado la inicialización del Servlet, el contenedor Web pasa al Servlet a un
estado llamado “en servicio”, es decir, disponible para los clientes y listo para responder a las
peticiones. Por tanto, para responder a las peticiones del cliente el contenedor Web llama al
método service(…). Este método se ejecuta siempre para todas las peticiones, con lo cual si lo
que queremos es un comportamiento único para cualquier petición, redefinimos éste método
y no hará falta redefinir ni doGet() ni doPost().
public void service(ServletRequest req, ServletResp onse res) throws
ServletException, IOException;
Por defecto, este método ya ha sido redefinido en la clase javax.servlet.http.HttpServlet para
llamar al método service(…) específico del protocolo HTTP que, a su vez llama al método
doXXX(…) correspondiente al método HTTP utilizado por el cliente para emitir su petición.
Sintaxis del método service(…) de la clase HttpServlet:
public void service(HttpServletRequest req, HttpSer vletResponse res) throws
ServletException, IOException;
Puede ser por tanto útil realizar la redefinición del método service(…) de la clase HttpServlet
en nuestros Servlets, si nuestro objetivo es realizar un mismo tratamiento para peticiones
emitidas por distintos métodos HTTP (GET, POST…).
4.3.3. Destrucción, método destroy()
Al detener el contenedor Web se destruirán las instancias de Servlets cargadas en memoria.
Sin embargo, antes de la destrucción, el contenedor Web ejecutará el método destroy() de
Tutorial J2EE Servlets #Hicham Qaissi#
8
cada Servlet. Por defecto este método no hace nada. Se aconseja de redefinir este método con
el fin de cerrar los recursos adecuadamente (conexiones JDBC, archivos, conexiones de red,
etc.) que hubiésemos podido abrir antes.
Public void destroy();
5. Llamada a un Servlet
5.1. Llamada del método doGet(…)
Este método es llamado principalmente en los casos siguientes:
• Cuando se introduce su URL directamente en la barra de direcciones del navegador.
• Cuando se hace clic sobre un hipervínculo que apunta al URL del Servlet.
Con un hipervínculo:
import javax.servlet.*; import javax.servlet.http.*; import javax.io.*; public class DoGetServlet extends HttpServlet { public void doGet(HttpServletRequest req, HttpServ letException res) throws ServletException, IOException { res.setContentType(“text/html”);
PrintWriter out = res.getWriter(); out.println(“<HTML><BODY>”); out.println(“<H1>Test Servlet DoGetServlet</H1>”) ; out.println(“</BODY></HTML>”); out.flush(); out.close(); }
}
Llamamos al anterior Servlet a través de una página HTML:
<HTML> <HEAD><TITLE>Test del Servlet DoGetServlet</TITLE>< /HEAD> <BODY> <P> <A HREF=”/MiWebApp/DoGetServlet”>Llamada del mét odo doGet(…) de DoGetServlet.java</A> </P> </BODY> </HTML>
5.2. Llamada del método doPost(…)
Se llama principalmente cuando en el envío de los datos introducidos en un formulario HTML
haciendo clic en un botón del tipo submit.
… <FORM action=”MiWebApp/DoPostServlet” method=”post” > …
Tutorial J2EE Servlets #Hicham Qaissi#
9
6. Configuración del Servlet: La interfaz ServletConfig
6.1. web.xml
Un objeto del tipo javax.servlet.ServletConfig representa la información de configuración de un
Servlet en una aplicación Web.
El contenedor Web crea un objeto de tipo javax.servlet.ServletConfig para cada elemento
<servlet></servlet> que está dentro del nodo raíz <web-app></web-app> declarado en el
descriptor de despliegue de la aplicación Web (web.xml). Entre la información de
configuración encontramos básicamente el nombre del Servlet y una posible lista de
parámetros con la forma nombre/valor. Dicha información puede ser recuperada luego por el
Servlet, preferentemente en su fase de inicialización, en la redefinición del método init(…).
Dentro de web.xml, un elemento <servlet> está compuesto como mínimo de:
• <servlet-name>: identifica el nombre del servlet.
• <servlet-class>: identifica el nombre completo de la clase del Servlet.
• Un nº variable de elementos (entre 0 y varios) <init-param> que permiten declarar los
parámetros de inicialización del Servlet. Cada elemento <init-param> corresponde a un
parámetro representado por una pareja <param-name> y <param-value>.
<web-app> <servlet> <servlet-name>…</servlet-name> <servlet-class>…</servlet-class> <init-param> <param-name>…</param-name> <param-value>…</param-value> <init-param> </servlet> </web-app>
6.2 Inicialización de un Servlet: redefinición del método init()
Tras cargar el Servlet en memoria, el contenedor Web pasa a la fase de inicialización del mismo
llamando a su método init(…) que por defecto no hace nada. Por tanto, se aconseja redefinir el
método init() de la clase javax.servlet.GenericServlet con el fin de:
• Cargar los recursos útiles para el funcionamiento del Servlet (conexiones JDBC,
archivos, conexiones de red…),
• Recuperar la información de configuración del Servlet, informada en web.xml
mediante los métodos de la interfaz ServletConfig.
Tutorial J2EE Servlets #Hicham Qaissi#
10
6.2.1. Métodos de la interfaz ServletConfig
• Método que permite recuperar una cadena de caracteres que contiene el valor de un
parámetro dado o, en su defecto el valor null si el parámetro no existe: public String getInitparameter(String nombre);
• Método para recuperar el conjunto de los nombres de los parámetros declarados por
el Servlet en un objeto del tipo java.util.Enumeration:
public java.util.Enumeration getInitParameterNames( );
• Método que devuelve una referencia sobre el contexto de ejecución (interfaz
ServletContext) del Servlet que permite interactuar con el contenedor Web de la
aplicación Web. public ServletContext getServletContext();
• Método que devuelve el nombre del Servlet declarado en web.xml o el nombre de la
clase del Servlet:
public String getServletName();
6.2.2. Ejemplo de uso de ServletConfig en el método init()
Se recuperan todos los parámetros del Servlet y se imprimen como respuesta del Servlet.
Vector vector = new Vector(); public void init() throws ServletEception{ Enumeration lstParams = getInitParameternames();
while(lst.hasMoreElements()){ String nomParam = (String)lstParams.nextElement( );
Vector.add(“{nombre=” + nomParam + “, valor=” + getInitParameter(nomParam) + “}”); }
} public void doGet(HttpServletRequest req, HttpServl etResponse res)
throws ServletException, IOException{ res.setContentType(“text/plain”); PrintWriter out = res.getWriter(); out.write(vector.toString()); out.flush(); out.close(); }
7. El contexto de aplicación: La interfaz ServletContext A diferencia de javax.servlet.ServletConfig que representa la información de configuración de
un Servlet en una aplicación Web, un objeto de tipo javax.servlet.ServletContext representa
la información de configuración de una aplicación Web. Cada Servlet de una misma aplicación
tiene pues acceso a dicha información.
Los métodos definidos en la interfaz permiten trabajar fundamentalmente con dos categorías
de datos:
• Acceder a parámetros de la aplicación Web declarados en su descriptor de despliegue.
• Crear, leer y borrar atributos de forma lógica, permitiendo compartir recursos entre
los Servlets de una misma aplicación.
Tutorial J2EE Servlets #Hicham Qaissi#
11
7.1. Obtención de un objeto ServletContext
Obtenemos un objeto de tipo javax.servlet.ServletContext llamando directamente al método
getServletContext().
Este método se define inicialmente en la interfaz javax.servlet.ServletConfig.
7.2. Parámetros de la aplicación Web.
Es posible declarar parámetros globales para toda la aplicación Web que pueden ser útiles
para declarar información susceptible de ser utilizada por varios Servlets de la aplicación Web:
• Nombre y mail del administrador, que pueden utilizarse para generar una página de
error.
• Nombre de host o IP de máquinas remotas que pueden utilizarse para el acceso a
recursos remotos.
• Nombre de la base de datos, controlador JDBC a utilizar, usuario y password para la
conexión.
• Etc.
7.2.1. Configuración de los parámetros en web.xml <web-app> <context-param> <param-name>…</param-name> <param-value>…</param-value> </context-param> </web-app>
7.2.2. Métodos para recuperación de los parámetros en web.xml public String getInitparameter(String nombre); public java.util.Enumeration getInitParameterNames( ); ServletContext application = getServletContext();
String nombre = application.getInitParameter(“nombr e”);
7.3. Atributos del context de la aplicación Web
Los atributos son parejas clave/valor, en donde la clave es una cadena de caracteres y el valor
es un objeto de cualquier tipo. Los atributos de una aplicación Web son pues variables globales
(llamadas también variables de aplicación) en el conjunto de elementos que participan en su
funcionamiento y que pueden ser compartidos simultáneamente por diversos Servlets y
clientes.
7.3.1. Métodos de gestión de los atributos del contexto de aplicación public void setAttribute(String nombre, Object obje to); public Object getAttribute(String nombre); public java.util.Enumeration getAttributenames(); public removeAttriute(String nombre);
8. Tratamiento de las peticiones: Las interfaces ServletRequest y
HttpServletRequest La interfaz HttpServletRequest hereda de ServletRequest y define comportamientos
suplementarios específicos para el protocolo HTTP. A continuación veremos los diferentes
grupos de métodos que pueden utilizarse para tratar las peticiones.
Tutorial J2EE Servlets #Hicham Qaissi#
12
8.1. Recuperación de los parámetros transmitidos en la petición: // especialmente para los campos de los formularios HTML public String getparameter(String nombre); public java.util.Enumeration getParameterNames(); // para recuperar los multiples valores que provien en de controles HTML, como // un conjunto de casillas de verificación <CHECKBO X>, una lista de selección // múltiple <SELECT> o un conjunto de valores que l leven el mismo nombre public java.util.Enumeration getParameterValues (S tring nombre);
8.2. Atributos del context de petición
Se utilizan cuando el Servlet le manda a una JSP los atributos para que ésa última que se
encarga de presentar la repuesta. La ventaja de esta técnica es que una vez se ha enviado la
respuesta al cliente, los objetos que representan la petición y la respuesta serán destruidos por
lo que tanto el contexto como sus atributos también serán destruidos. Los atributos son
parejas clave/valor.
public void setAttribute(String nombre, Object obje to); public Object getAttribute(String nombre); public java.util.Enumeration getAttributeNames(); public void removeAttribute(String name);
8.3 Gestión del flujo de entrada
La interfaz javax.servlet.ServletRequest define 2 métodos que permiten leer el cuerpo de la
petición HTTP, ya sea como un flujo binario o como un flujo de caracteres (ambos métodos no
pueden utilizarse conjuntamente sobre la misma petición ya que obtendríamos una excepción
del tipo java.lang.IllegalStateException).
• Método que permite recuperar el cuerpo de la petición HTTP como objeto de flujo
binario representado por un objeto de tipo javax.servlet.ServletInputStream.
public ServletImputStream getInputStream() throws j ava.io.IOException;
• Método que permite recuperar el cuerpo de la petición HTTP en forma de un buffer de
caracteres representado por un objeto de tipo java.io.BuferredReader.
public java.io.BufferedReader getReader() throws ja va.io.IOException;
8.4 Recuperación de información sobre el URL de la petición
Existen métodos que permiten obtener cierta información sobre el URL de la petición HTTP:
protocolo, contexto de la aplicación Web, ruta del Servlet…
• Método que devuelve el nombre del protocolo utilizado por el cliente para emitir su
petición. Por ejemplo: http, https, ftp: public String getScheme();
• Método que devuelve como cadena de caracteres que empieza con “/”, la parte del
URL de la petición correspondiente al nombre de contexto de la aplicación Web: public String getContextPath();
• Método que devuelve el nombre del método HTTP (GET, POST, DELETE, PUT…)
utilizado por el cliente para emitir su petición: public String getMethod();
Tutorial J2EE Servlets #Hicham Qaissi#
13
• Método que devuelve la cadena de petición contenida en el URL tras la ruta del
recurso llamado, o el valor null si no existe. Generalmente devuelve
?<param1>=<valor1>&<param2>=<valor2>… public String getQueryString();
• Método que devuelve la parte del URL contenido entre el nombre de protocolo y la
cadena de petición, por ejemplo en una petición HTTP como “GET
http://misitio/servlet/MiServlet?param1=valor1 HTTP/1.1”, el valor devuelto es
“/servlet/miServlet”: public String getRequestURL();
• Método que devuelve el URL que el cliente ha utilizado para emitir su petición: public String getRequestURL();
• Método que devuelve la parte del URL que llama al Servlet/JSP compuesta de la ruta y
del nombre o el alias del Servlet: public String getServletPath();
8.5 Recuperación de información del cliente public String getRemoteAddr(); public String getRemoteHost(); public String getRemoteUser();
8.6 Recuperación de información sobre el servidor public String getServerName();
public String getServerPort();
8.7 Recuperación de información en el encabezado HTTP
• Método que devuelve el valor del encabezado dado, pasado como parámetro, o el
valor null si el encabezado no existe. El nombre del encabezado es sensible a las
mayúsculas y minúsculas: public String getHeader(String name);
• Método que devuelve como objeto del tipo java.util.Enumeration el conjunto de
valores del encabezado de la petición especificada como parámetro: public java.util.Enumeration getHeaders(String name );
• Método que devuelve como objeto del tipo java.util.Enumeration el conjunto de
nombres de los encabezaos contenidos en la petición: public java.util.Enumeration getHeadersNames(String name);
9. Tratamiento de las respuestas ServletResponse y
HttpServletResponse
9.1 Declaración del tamaño y tipo del contenido de respuesta
• Método que permite especificar el tipo de contenido del cuerpo de la respuesta HTTP
(Corresponde a definir el encabezado HTTP Content-Type). Por ejemplo text/html para
HTML, text/plain para texto plano, application/pdf para documento Adobe pdf… public void setContentType(String tipo);
• Método que especifica el tamaño del contenido de la respuesta HTTP: public void setContentLength(int tamaño)
Tutorial J2EE Servlets #Hicham Qaissi#
14
9.2 Introducir información en el encabezado HTTP
• Método que permite añadir encabezado en la respuesta HTTP, con el nombre y valor
especificados como parámetros. Si el encabezado ya existe, los nuevos valores
reemplazarán a los antiguos. El Método containsHeader(…) puede ser llamado
inicialmente para sabe si un encabezado existe o no en el encabezado de la respuesta: public void setHeader(String name, String value);
• Lo mismo que el método anterior pero este permite a un encabezado tener múltiples
valores: public void adddHeader(String name, String value);
• Método booleano que dice si un encabezado existe o no en la respuesta HTTP public boolean containesHeader(String namen);
9.3 Gestión del flujo de salida
La interfaz javax.servlet.ServletResponse define dos métodos que devuelven objetos que
permiten escribir el contenido de la respuesta HTTP (No podemos utilizar ambos métodos
sobre la misma respuesta, de lo contrario obtendremos una excepción del tipo
java.lang.IllegalStateException). Estos dos métodos permiten escribir el contenido del cuerpo
de la respuesta HTTP. Debemos especificar en primer lugar si fuera necesario, la información
de encabezado de la respuesta HTTP. Por ejemplo, el tipo MIME del contenido indicado por la
llamada del método setContent-Type(…) debe hacerse obligatoriamente antes.
• Método de gestión del flujo de salida: método que devuelve un objeto del tipo
javax.servlet.ServletOutputStream que permite escribir datos de forma binaria en el
cuerpo de la respuesta. Una vez escritos los datos se recomienda llamar al método
flush() sobre el objeto javax.servlet.ServletOutputStream con el fin de validar el envío
de la respuesta. public ServletOutputStream getOutputStream() throws java.io.IOException;
javax.servlet.ServletOutputStream out = res.getOutp utStream(); out.println(<datos>); out.println(<datos>); … out.flush(); out.close();
• Método que devuelve un objeto de tipo java.io.PrintWriter que permite escribir datos
en formato de texto en el cuerpo de la respuesta. Tras haber escrito los datos se
aconseja llamar a flush() sobre java.io.PrintWriter. public java.io.PrintWriter getWriter() throws java. io.IOException, javax.servlet.PrintWriter out = res.getPrintWriter( ); out.println(<datos>); out.println(<datos>); … out.flush();
out.close();
9.4 Gestión de la puesta en memoria intermedia
La interfaz javax.servlet.ServletResponse define un conjunto de métodos que permiten
gestionar la puesta en memoria intermedia (buffer) de los datos mediante la respuesta HTTP.
Tutorial J2EE Servlets #Hicham Qaissi#
15
Si el volumen de los datos a enviar al cliente es importante, se recomienda disminuir el tamaño
de la memoria intermedia, para que los datos sean enviados por paquetes, lo que permite que
el cliente reciba los datos más rápidamente.
• Método que devuelve el tamaño actual del buffer utilizado para el almacenamiento
temporal del cuerpo de la respuesta HTTP. Si no se utiliza devuelve 0. public int getBufferSize();
• Método que especifica el tamaño del buffer. Este método debe ser llamado antes de
escribir cualquier dato: public void setBufferSize(int size);
• Método que envía al cliente todo el contenido del buffer. Este método indica enviar la
respuesta al cliente, con lo cual no puede enviarse ningún otro dato. public void flushBuffer() throws java.io.IOExceptio n
• Método que indica si la respuesta ha sido enviada o no. public boolean isCommited();
• Método que suprime el contenido del buffer. Genera una exception
java.lang.IllegalStateException si los datos ya se han enviado. public void reset();
• Método que suprime el contenido del buffer sin suprimir los encabezados. public void resetBuffer();
9.5 Codificación de URL
Los siguientes métodos permiten incluir el identificador de la sesión HTTP en los URL devueltos
al cliente, con el fin de que pueda seguirse la navegación a través de la aplicación Web. Estos
métodos permiten habilitar el mecanismo de reescritura de URL cuando el navegador Web del
cliente no soporta o no autoriza las cookies.
• Método que codifica el URL pasado como parámetro, incluyendo el identificador de la
sesión si fuese necesario. Este método permite preservar el estado de la sesión del
usuario al navegar en la aplicación Web. public String encodeURL(String url);
• Método que codifica el URL pasado como parámetro incluyendo el identificador de
sesión. Este método se utiliza para codificar los URLs de redireccionamiento que son
enviados a los clientes con el método sendRedirect(…). public String encodeRedirectURL(String url);
9.6 Envío de errores y de estados HTTP y redirección de URL
Este grupo de métodos permite el envío de respuestas en ciertos casos particulares del estado
de la aplicación Web.
• Métodos que pueden enviar un código de error al cliente, entre las constantes
definidas en las interfaz javax.servlet.HttpServletResponse, como por ejemplo,
SC_NOT_FOUND (404) o SC_SERVICE_UNAVAILABLE (503). Por defecto, el contenedor
Web devuelve una página HTML compuesta por el mensaje de error, si éste ha sido
especificado. Si en web.xml contiene una declaración de página de error que
corresponde al código de error, dicha página será llamada por el contenedor Web,
para proporcionar una respuesta al cliente. Si la respuesta ya ha sido enviada al cliente
se genera una excepción java.lang.IllegalStateException.
Tutorial J2EE Servlets #Hicham Qaissi#
16
public void sendError(int sc) throws java.io.IOExce ption; public void sendError(int sc, String message);
• Método que permite aplicar un código de estado a la respuesta HTTP cuando no existe
ningún error como, por ejemplo SC_OK (200) o SC_CONTINUE (100) public void sendStatus(int sc);
• Método que redirecciona al cliente a otro recurso Web, que puede estar o no en la
misma aplicación. El URL del recurso destino puede ser absoluto o relativo ya que el
contenedor Web se encarga de convertir los URLs relativos en URLs absolutos antes de
enviar al cliente la orden de redireccionamiento. Si la respuesta ya ha sido enviada al
cliente se generará una excepción del tipo java.lang.IllegalStateException. public void sendRedirect(String url) throws java.io .IOException
Esta manera de redireccionamiento tiene la desventaja de perder la request, la response y la
información almacenada en ellas. Hay otra manera para redireccionar hacia un recurso web,
con el RequestDispacher.
Para asociar errores HTML y excepciones lanzadas por nuestra aplicación a páginas de error
personalizadas para la aplicación, tenemos que definir en web.xml los siguientes nodos: <error-page> <error-code>404</error-code> <location>jsp/error_400.jsp</location> </error-page> <error-page> <error-code>500</error-code> <location>jsp/error_500.jsp</location>
</error-page>
10. Sincronización de los procesos: La interfaz
SingleThreadModel
10.1. Sin la implementación de la interfaz SingleThreadModel
Sin la implementación de javax.servlet.SingleThreadModel un Servlet funciona en un entorno
multitarea. Es decir, que para cada petición recibida por un Servlet, el contenedor Web crea
una hebra que ejecutará el método de servicio de una instancia del Servlet. Según las
implementaciones, un contenedor Web puede gestionar una única instancia para cada Servlet,
o bien un conjunto de ellas. Este principio de funcionamiento puede generar problemas si el
método de servicio trabaja con variables de instancia del Servlet, porque cada hebra puede
modificar el valor de dichas variables, con independencia de la lógica de procesamiento de las
otras hebras.
Debemos ser capaces de garantizar un funcionamiento aislado de cada hebra. Para ello, es
necesario que la clase de Servlet implemente la interfaz javax.servlet.SingleThreadModel.
10.2. Con la implementación de la interfaz SingleThreadModel
Con su implementación, el contenedor Web supone que una instancia del Servlet sólo puede
ser ejecutada concurrentemente por una única hebra.
Tutorial J2EE Servlets #Hicham Qaissi#
17
Según la implementación del contenedor Web el funcionamiento es distinto:
• Si el contenedor Web supone una única instancia para cada Servlet, gestiona entonces
colas de espera para las hebras, para satisfacer las peticiones de los clientes. Cada
petición espera su turno para ser servida por el Servlet. En este caso, el tiempo de
procesamiento de las peticiones se ve degradado.
• Si por el contrario, el contenedor Web supone un pool de instancias para cada Servlet,
sacará entonces una instancia del pool para satisfacer el procesamiento de una
petición y, una vez que el procesamiento acabe, devolverá la instancia al pool. En este
caso, si el contenedor Web debe generar un volumen de peticiones, los recursos de
memoria del servidor estarán fuertemente solicitados con lo que la respuesta será más
lenta.
La interfaz javax.servlet.SingleThreadModel no define ningún método, tan sólo aporta un
comportamiento suplementario al Servlet que la implementa.
Es importante pensar con detenimiento la aplicación Web antes de implementar
SingleThreadModel. Cuya utilización implica que el contenedor Web llama al método de
servicio en un bloque sincronizado. En lugar de sincronizar todo el método se servicio,
podremos entonces mejorar el rendimiento sincronizando únicamente las instrucciones
sensibles, utilizando uno o varios bloques sincronizados (synchronized(Object){…}).
Ejemplo:
Object obj = new Object(); … public void doXXX(HttpServletrequest req, HttpServl etResponse res){
… Synchronized(obj){ … }
}
11. Los filtros: la interfaz Filter
11.1. Principios de utilización
Son clases que permiten realizar procesamiento sobre o a partir de:
• Peticiones que provienen de los clientes, antes de que sean procesadas por los
Servlets.
• Respuestas provenientes de los Servlets antes de que sean enviadas a los clientes.
Por ejemplo, se pueden utilizar para:
• Descomprimir los datos enviados por los clientes y comprimir los datos enviados a los
clientes.
• Desencriptar las peticiones de los clientes y encriptar las respuestas de los Servlets.
• Autentificar los clientes.
• Aplicar una transformación XSLT sobre datos XML.
Tutorial J2EE Servlets #Hicham Qaissi#
18
Es posible encadenar varios filtros para que se ejecuten secuencialmente varios procesos sobre
un Servlet o sobre un grupo de ellos, ya sea sobre las peticiones o sobre las respuestas, para
ello bastará con declararlos según su orden de procesamiento en web.xml.
11.2. Implementación: La interfaz Filter
11.2.1. La interfaz Filter
Un filtro es una clase que implementa javax.servlet.Filter y redefine los métodos init(…),
doFilter(…) y destroy() que corresponden al ciclo de vida del filtro.
import javax.servlet.*; import java.io.*; public class MiFiltro implements Filter{ private FilterConfig filterConfig = null; public void init(FilterConfig filterConfig) throw s ServletException{ this.filterConfig = filterConfig; … } public void doFilter(ServletRequest req, ServletR esponse res, FilterChain chain) throws ServletException, IOException{ if(filterConfig == null) return; … … chain.doFilter(req, res); … } public void destroy(){ this.filterConfig = null; … } }
El método init(FilterConfig) corresponde a la inicialización del filtro que es llamado por el
contenedor web justo antes de que este haya instanciado la clase del filtro,
javax.servlet.FilterConfig permite recuperar parámetros de inicialización del filtro, definidos en
web.xml.
doFilter(ServletRequest , ServletResponse, FilterChain ) corresponde al trabajo que debe
realizar el filtro sobre la petición y/o la respuesta, que es llamado por el contenedor Web cada
vez que una pareja petición/respuesta es pasada a la cadena de filtros para procesamiento.
FilterChain permite llamar al siguiente filtro declarado en web.xml (cadena de filtros) o llamar
al recurso Web si el filtro Web es el último de la cadena.
destroy() corresponde a la fase de finalización del filtro que permite destruir los recursos
utilizados por el filtro que llamado por el contenedor Web justo antes de la destrucción de la
instancia del filtro.
11.2.2. La interfaz Filterconfig
Define unos métodos que permiten acceder a la información de configuración del filtro
declarados en web.xml:
Tutorial J2EE Servlets #Hicham Qaissi#
19
• Método que devuelve el nombre del filtro declarado en web.xml (<filter-name>) public String getFilterName();
• Método que devuelve una referencia sobre el contexto de la aplicación public ServletContext getServletContext();
• Método que devuelve el valor de un parámetro dado declarado en web.xml. public String getInitParameter(String nombre);
• Método que devuelve como objeto java.util.Enumeration los nombres de los
parámetros de inicialización declarados en web.xml. public java.util.Enumeration getInitParameterNames( );
11.2.3. La interfaz FilterChain
Representa una vista sobre la lista de filtros configurados en web.xml. Define un método que
permite llamar al siguiente filtro declarado en web.xml o llamar al recurso web cuando se llega
al último filtro.
public void doFilter(ServletRequest req, ServletR esponse res) throws ServletException, java.ioIOException;
Ejemplo de definición de un filtro en web.xml:
… <filter> <filter-name>Registro</filter-name> <desription>descripción del filtro</description> <filter-class>paquete/RegistroFilter</filter-clas s> <init-param> <param-name>modo</param-name> <param-value>DETALLE</param-value> </init-param> </filter> … <filter-mapping> <filter-name>Registro</filtro-name> <url-pattern>/*</url-pattern> </filter-mapping> …
Ejemplo de un Filtro:
Packaged paquete; import javax.servlet.*; import javax.servlet.http.*; import java.io.* public class RegistroFilter implements Filter { private FilterConfig filterConfig = null; private ServletContext context = null; private String mode = null; public void init(FilterConfig filterConfig){ this.filterConfig = filterConfig; context = filterConfig.getServletContext(); log(“Inicialización del filtro: ” + filterConfi ggetFilterName()); mode = filterConfig.getInitParameter(“modo”); if(mode == null || !mode.equalsIgboreCase(“simp le”) || !mode.equalsIgnoreCase(“detallado”)) mode = “simple ”; log(“modo de registro: ” + mode); } public void doFilter(ServletRequest req, ServletR esponse res, FilterChain chain) throws ServletException, IOException{ HttpServletRequest httpReq = (HttpServletReques t)req;
Tutorial J2EE Servlets #Hicham Qaissi#
20
log(“*** Ha entrado una petición”); chain.doFilter(req, res);//saltar al siguiente Filtro } public void destroy(){ log(“Destrucción del filtro: ” + filterConfig.get FilterName()); filterConfig = null; } private void log(“String message”){ context.log(message); } }
12. Los eventos de una aplicación Web
12.1. Principios de funcionamiento y utilización
La escucha de los eventos es una novedad de la API Servlet 2.3 que proporciona las interfaces
Listeners que permiten interceptar los eventos de una aplicación Web sobre el ciclo de vida de
los objetos de tipo javax.servlet.ServletContext y javax.servlet.http.HttpSession.
Para el contexto de ServletContext, podemos interceptar los eventos que indican si la
aplicación Web está o no disponible, así como los eventos que permiten la notificación de la
adición, modificación o supresión de atributos en el contexto de la aplicación Web.
Para el contexto de HttpSession, podemos interceptar eventos referentes a la activación y
desactivación de la sesión HTTP, así que como eventos que permiten la notificación de la
adición, modificación y supresión de atributos en el contexto de la sesión de un usuario.
Interceptar estos eventos pueden ser útiles para:
• Generar mensajes de seguimiento de la aplicación Web (logs).
• Generar la creación y la destrucción de conexiones JDBC.
• Generar la persistencia de atributos.
• Inicializar los contextos de aplicación y/o de sesión tras su creación.
11.2. Los eventos de contexto de la aplicación Web.
11.2.1. Notificación de la creación/destrucción del contexto de la aplicación Web: la
interfaz ServletContextListener
La interfaz javax.servlet.ServletContextListener proporciona métodos que permiten notificar
el estado de disponibilidad de una aplicación Web, correspondiente a la creación/destrucción
del contexto de la aplicación Web por el contenedor Web.
Si queremos ser notificados de dichos eventos, debemos crear una clase que implemente la
interfaz javax.servlet.ServletContextListener y redefinir los métodos:
• public void contextInitialized(ServletContextEvent sce);
• public void contextDetroyed(ServletContextEvent sce );
Tutorial J2EE Servlets #Hicham Qaissi#
21
ServletContextEvent proporciona el método getServletContext() que permite recuperar el
contexto de la aplicación Web (Objeto ServletContext):
ServletContext sc = sce.getServletContext();
12.2.3. Notificación de adición/modificación/supresión de atributos de contexto de
la aplicación Web: la interfaz ServletContextAttributeListener
La interfaz javax.servlet.ServletContextAttributeListener proporciona unos métodos que
permiten que se nos notifique la adición, modificación y supresión de los atributos de contexto
de la aplicación Web. Para ello, debemos crear una clase que implemente dicha interfaz y
redefinir los siguientes métodos:
• public void attributeAdded(ServletContextAttrinuteE vent scab);
• public void attributeReplaced(ServletContextAttrinu teEvent scab);
• public void attributeRemoved(ServletContextAttrinut eEvent scab);
ServletContextAttrinuteEvent proporciona dos métodos, getName() y getValue() que
permiten recuperar respectivamente el nombre y el valor del atributo afectado por el
evento.
12.3. Los eventos de sesión HTTP
12.3.1. Notificación de la creación/destrucción de una sesión HTTP: La interfaz
HttpSessionListener
La interfaz javax.servlet.http.HttpSessionListener proporciona métodos que nos permiten ser
notificados de la creación/destrucción de una sesión HTTP en la aplicación Web. Para ello,
debemos crear una clase que implemente HttpSessionListenner y redefinir los métodos:
• public void sessionCreated(HttpSessionEvent hse);
• public void sessionDestroyed(HttpSessionEvent hse);
El objeto HttpSessionEvent proporciona el método getSession() que permite recuperar una
referencia sobre el objeto javax.servlet.http.HttpSession.
12.3.2. Notificación de la activación/desactivación de una sesión HTTP: la interfaz
HttpSessionActivationListener
La interfaz HttpSessionActionListener proporciona unos métodos que nos permiten estar
notificados de la activación de una sesión HTTP en la aplicación Web. Para ello deberemos
crear una clase que implemente la interfaz HttpSessionActivationListener y redefinir los
siguientes métodos:
• public void sessionWillPassivate(HttpSessionEvent h se);
• public void sessionDidActivate(HttpSessionEvent hse );
12.3.3. Notificación de la adición/modificación/supresión de atributos de una sesión
HTTP: la interfaz HttpSessionAttributeListener
La interfaz javax.servlet.http.HttpSessionListener proporciona métodos que nos permiten ser
notificados de la adición, modificación y supresión de atributos de conteto de la sesión HTTP.
Para ello, debemos crear una clase que implemente dicha interfaz y redefinir los métodos:
• public void attributeAdded(HttpSessionBindingEvent hsbe);
• public void attributeReplaced(HttpSessionBindingEve nt hsbe);
Tutorial J2EE Servlets #Hicham Qaissi#
22
• public void attributeRemoved(HttpSessionBindingEven t hsbe);
El objeto HttpSessionBindingEvent proporciona dos métodos, getName() y getValue() que
permiten respectivamente recuperar el nombre y el valor del atributo afectado por el
evento; también proporciona getSession() para recuperar la sesión.
12.4. Despliegue
El escuchador de eventos en el contexto de aplicación/sesión se declara en el fichero web.xml.
Tan solo tenemos que asignar el nombre de la clase. La declaración del escuchador se hace
entre los elementos <filter-mapping> y <servlet>.
… <listener> <listener-class>…</listener-class> </listener>
12.5. Ejemplo de puesta en marcha.
13. Mantener el estado de los clientes El protocolo HTTP es un protocolo desconectado, el servidor considera cada petición como
proveniente de un cliente distinto. El protocolo es, pues incapaz de conservar un estado
distinto para cada cliente. Necesitamos de un contexto de almacenamiento de datos, propio
de la sesión de navegación de cada uno de los clientes. Existen distintas posibilidades que
permiten almacenar los datos propios de un cliente.
13.1. Las Cookies: la clase Cookie.
13.1.1. ¿Qué es?
Una cookie es un elemento de datos que puede ser enviado por el servidor y que tiene como
destino el navegador Web que la almacena en función de fecha de expiración en memoria. Su
uso no está recomendado ya que el usuario puede configurar su navegador para que las
rechace.
13.1.2. Estructura
Una cookie está compuesta de una pareja nombre/valor y de un conjunto de propiedades que
pueden ser asignados por defecto por el servidor o fijadas por el desarrollador:
• El nombre de dominio del servidor al que está ligada la cookie (www.dominio.com).
• El contexto de la aplicación Web al que está ligada a cookie. Por defecto es “/”, que
indica que la cookie será recibida por todas aplicaciones Web del dominio sobre las
que el usuario envíe peticiones. En caso que esta situación no sea deseable, podemos
especificar el contexto de aplicación Web (“/MiWebApp”), para indicar cual es la
aplicación a la que está ligada la cookie.
• La duración de vida expresada en segundos. La mayor parte de los navegadores
guardan las cookies en memoria hasta el momento en que se cierran. En este caso, si
la duración de vida de una cookie no ha llegado a su expiración, el navegador
almacenará entonces la cookie en un archivo en la máquina del cliente. Un valor -1,
indica que la cookie expira inmediatamente tras el cierre del navegador.
Tutorial J2EE Servlets #Hicham Qaissi#
23
• La opción de seguridad, cuyo valor es de tipo lógico, indica que la conexión debe ser
segura (HTTPS) antes de autorizar el envío de la cookie al servidor.
• Disponemos también de una propiedad que permite aportar un comentario y de una
propiedad que permite dar un número de versión de conformidad de la cookie con las
especificaciones.
13.1.3. Trabajar con las cookies: la clase Cookie.
Constructor: el nombre de la cookie no puede tener caracteres como la coma, el punto y coma
o empezar con $.
public Cookie(String name, String value);
Métodos:
• public String getname(); • public String getValue(); • public void setValue(); • public String getDomain(); • public void setDomain(String domain); • public String getPath(); • public void setPath(String path); • public int getMaxAge(); • public void setMaxAge(int segonds); • public boolean getSecure(); • public void setSecure(Boolean flag); • public String getComment(); • public void setComment(String comment); • public int getVersion(); • public void setVersion(int version); • public Objecto clone();
13.1.4. Enviar cookies en la respuesta HTTP
La interfaz javax.servlet.http.HttpServletResponse define un método que permite añadir una
cookie en la repuesta HTTP que le será enviada al cliente.
public void addCookie(Cookie cookie);
Ejemplo de manipulación:
public void doXXX(HttpServletRequest req, HttpServl etResponse res) throws ServletException, IOException{ … Cookie cookie1 = new Cookie(“KeyCookie1”, “valCoo kie1”); Cookie cookie2 = new Cookie(“KeyCookie2”, “valCoo kie2”); … res.addCookie(cookie1); res.addCookie(cookie2); … }
13.1.5. Recuperación de cookies en la petición HTTP
La interfaz javax.servlet.http.HttpServletRequest define un método que permite recuperar en
forma de tabla el conjunto de cookies que el cliente ha enviado con su petición HTTP, devuelve
null si no se ha enviado ninguna cookie.
Tutorial J2EE Servlets #Hicham Qaissi#
24
public Cookie[] getCookies();
Ejemplo de manipulación:
public void doXXX(HttpServletRequest req, HttpServl etResponse res) throws ServletException, IOException{ … Cookie[] cookies = req.getCookies(); if(cookies != null){ Cookie cookie = null; for(int i = 0; i < cookies.length; i++){ cookie = cookies[i]; System.out.println(“Cookie: ” + cookie.getName () + “, valor = “ + cookie.getValue()); } } … }
13.1.6. Suprimir una cookie
Para ello, debemos reenviar una cookie en la petición HTTP con los parámetros siguientes:
mismo nombre, valor igual a una cadena vacía, ciclo de vida igual a -1 (destrucción inmediata
tras el cierre del navegador):
… Cookie cookie = new Cookie(“nombreCookie”, “”); cookie.setMaxAge(-1); res.addCookie(cookie); …
13.2. Las sesiones: La interfaz HttpSession
13.2.1. ¿Qué es?
Una sesión es un contexto de almacenamiento de datos y contenido gestionado por el servidor
Web que permite identificar a usuarios mientras dure su navegación en la aplicación Web. Las
sesiones son pues únicas y corresponden a cada cliente de un servidor Web. No son
persistentes, quiere decir, que cada vez que un usuario visita un sitio se crea una nueva sesión.
El ciclo de vida de una sesión es parametrizable en el propio Servidor Web y en la aplicación.
Por lo general su valor por defecto es de 30 minutos, por lo que al cabo de 30 minutos de
inactividad la sesión se destruye.
13.2.2. ¿Cómo obtener una sesión? public HttpSession getSession(); //El siguiente método devuelve la sesión o crea y d evuelve una nueva si la //petición (HttpServletRequest) no contiene id de s esión. Si create vale false //y la sesión no existe, el método devuelve null public HttpSession getSession(Boolean create);
13.2.3. Trabajar con una session: La interfaz HttpSession
Lista de métodos de la interfaz javax.servlet.http.HttpSession:
• public void setAttribute(String nombre, Object obje t); • public Objectt getObject(String name); • public java.util.Enumeration getAttributeNames(); • public void removeAttribute(); • public Boolean isNew();
Tutorial J2EE Servlets #Hicham Qaissi#
25
Normalmente una sesión muere por 3 razones, cuando se cierra el navegador Web, por
timeout o por el siguiente método: • public void invalidate();
Definir el timeout (en segundos): • public void setMaxInacctiveintervale(int interval); • public int getMaxInactiveInterval();
Método que devuelve en milisegundos a partir del 1 de enero de 1970, la fecha de
creación de la sesión HTTP: • public long getCreationTime();
Método que devuelve el id de la sesión: • public String getId(); • public long getLastAccessedTime(); //en milisegundo s
Método que devuelve una referencia del contexto de aplicación Web al que está asociada
la sesión actual: • public ServletContext getServletContext()
Ejemplo de manipulación:
public void doXXX(HttpServletRequest req, HttpServl etResponse res) throws ServletException, IOException{ … // recuperación de la session HttpSession session = req.getSession(); // si no es nueva, se destruye y se crea una nuev a if(!session.isNew()){ sesion.invalidate(); session = getSession(true); } … // recuperación de los parámetos de la petición String userName = req.getParameter(“user”); String password = req.getParameter(“pass”); … // almacenamiento de los parámetros como atributo s del context de sesión sesion.setAttribute(“user”, userName); sesión.setAttribute(“pass”, password); … }
13.3. Las sesiones y la reescritura de URL
Sesión HTTP y cookies:
El mecanismo de gestión de las sesiones de usuario utiliza las cookies para mantener, por
defecto, el contexto de la sesión con un usuario concreto.
Al crear una sesión sobre el servidor, éste reenvía en la respuesta HTTP una cookie que
contiene el ID de la sesión a la que el cliente está ligado. Posteriormente la cookie se incluirá
en cada petición enviada por el cliente, lo que permite al servidor ligar la sesión a un usuario
concreta.
Pero ¿qué pasaría si el cliente desactiva las cookies en su navegador Web? El usuario perderá
su vínculo con la sesión, porque cada sesión corresponderá a una nueva sesión sobre el
servidor y se perderá por tanto el contexto de sesión entre la aplicación Web y el usuario.
Por tanto se hace necesaria otra alternativa a las cookies: la reescritura de URL.
Tutorial J2EE Servlets #Hicham Qaissi#
26
Sesión HTTP y la reescritura de URLs:
Con una petición podemos saber, por ejemplo, si el navegador del cliente soporta/autoriza las
cookies. En principio el mecanismo de reescritura de URLs es simple: en lugar de reenviar una
cookie al cliente, se trata de reescribir las URLs incluidas en la respuesta HTTP, añadiendo un
parámetro cuyo valor corresponde al ID de sesión HTTP del cliente, las URLs afectadas son:
• Las del formulario HTML (Marcador <FORM action=…>)
• Los hipervínculos (marcados <a href=…>)
• Las órdenes de redirección.
Así, cada vez que el cliente envía un formulario, hace clic sobre un hipervínculo o recibe una
orden de redirección, envía al servidor junto con su petición el ID de sesión, lo que permite
que el servidor pueda relacionar cada cliente con el contexto de sesión HTTP que le
corresponde.
Para que el servidor pueda poner en marcha la reescritura de URLs, deberemos preverlo en el
código de los Servlets/JSPs, utilizando para ello funciones de codificación como veremos a
continuación.
La interfaz HttpServletResponse define 2 métodos que permiten codificar las URLs para que el
servidor pueda reescribirlas en caso de que el navegador Web del cliente no soporte o no
autorice el uso de las cookies.
Por tanto, se recomienda encarecidamente la utilización de éstos métodos en todos los
Servlets/JSPs que reenvíen a los clientes URLs a recursos dinámicos (Servlets/JSPs), para que
dichos recursos dinámicos puedan tener acceso al contexto de sesión del usuario actual.
• Método que permite codificar el URL pasada como parámetro, incluyendo el
identificador de sesión si fuese necesario. Este método permite preservar el estado de
la sesión de usuario de su navegación en la aplicación Web, en el caso de que su
navegador no soporte o no autorice el uso de cookies: public String encodeURL(String url);
• Mismo principio que el método anterior, pero en este caso el método se utiliza para
codificar las URLs de redirección que son enviadas a los clientes que utilizan el método
sendRedirect(…): public String encodeRedirectURL(String url);
Ejemplo para el atributo action de un formulario HTML:
Out.println(“<FORM action=\”” + response.encodeURL(“/MiWebApp/servlet/MiServlet”) + “\”>”);
Ejemplo para el atributo href de un hipervínculo:
Out.println(“<A href=\”” + response.encodeURL(“/MiW ebApp/servlet/MiServlet”) +
“\”>”);
Ejemplo para URL de redirección:
Tutorial J2EE Servlets #Hicham Qaissi#
27
response.redirect(response.encodeURL(“/MiAppWeb/jsp /InfoCliente.jsp”));
14. Colaboración entre Servlets: La interfaz RequestDispacher
14.1. ¿Qué es?
RequestDispacher es la base de la arquitectura MVC. Un objeto de tipo
javax.servlet.RequestDispacher es creado por el contenedor Web para cada aplicación Web y
actúa como un enrutador de peticiones o respuestas HTTP sobre los recursos Web de la
aplicación Web actual. Así que podemos utilizarlo para:
a. Realizar un seguimiento del proceso de una petición HTTP hacia otro recurso
Web.
b. Incluir el contenido de otro recurso Web en la respuesta HTTP.
14.2. Obtener un objeto RequestDispacher
Las interfaces ServletContext y ServletRequest definen el método getRequestDispacher(…)
para obtener un objeto RequestDispacher sobre un recurso de la aplicación Web Actual.
public RequestDispacher getRequestDispacher(String ruta);
El parámetro ruta debe empezar por un signo “/”, que permite referenciar al contexto de la
aplicación Web actual. Luego debe completarse para indicar así la ruta de acceso a un recurso
Web destino de la aplicación. Por ejemplo “/servlet/MiServlet” o “/jsp/MiJSP.jsp”.
Si deseamos utilizar el objeto RequestDispacher de otro contexto de aplicación Web (otra
aplicación web), podemos utilizar el método getContext(…) de la interfaz ServletContext que
devuelve un objeto ServletContext correspondiente al contexto de la aplicación Web
deseada, sobre el que podemos recuperar un objeto RequestDispacher.
Una vez tenemos el objeto RequestDispacher, podremos llamar ya sea al método que permite
delegar el tratamiento de la petición HTTP al recurso, o al método que permite incluir el
contenido del recurso en la respuesta HTTP. El objeto RequestDispacher permite pues
encadenar recursos Web.
a. La delegación:
Consiste en transmitir la petición HTTP a otro recurso Web que se encargará de su
procesamiento y que puede, a su vez, transmitir la respuesta a otro recurso. La delegación
puede utilizarse por ejemplo para llamar a un Servlet que va a realizar procesos especiales
cuando el primer Servlet haya realizado los procesos básicos. Para ello RequestDispacher
define el método forward(…):
public void forward(ServletRequest request, Servlet Response response) throws ServletException, IOException;
Ejemplo:
Tutorial J2EE Servlets #Hicham Qaissi#
28
RequestDispacher rd = getRequestDispacher (“ruta_destino”) rd.forward(req, res);
Nota: La diferencia entre sendRedirect(…) y forward(…) es que con sendRedirect(…) se
pierden la petición y la respuesta (ServletRequest y ServletResponse), con lo cual no
podemos enviarle al recurso destino información grabada sobre ServletRequest y
ServletResponse.
b. La inclusión:
Consiste en incorporar el contenido de otro recurso Web en la respuesta HTTP que se
transmitirá al cliente. Este recurso Web incluido puede realizar procesos sobre la petición, así
como incluir otro recurso Web en la respuesta HTTP. La inclusión puede utilizarse por ejemplo,
para incluir de forma sistemática en las respuestas enviadas a los clientes un cierto
encabezado y un pie de página, representadas por dos páginas HTML en caso de que el
contenido sea estático, o por dos páginas JSP si una parte del contenido es dinámico. Para ello
la interfaz javax.servlet.RequestDispacher define el método include(…).
public void include(ServletRequest request, Servlet Response response) throws ServletException, IOException;
Tutorial J2EE Servlets #Hicham Qaissi#
29
���� ��