J2EE Servlets Tutorial

29
Tutorial J2EE Servlets #Hicham Qaissi# 1 Tutorial J2EE Servlets Hicham Qaissi [email protected]

description

Un tutorial bastante completo de la API J2EE Servlets.

Transcript of J2EE Servlets Tutorial

Page 1: J2EE Servlets Tutorial

Tutorial J2EE Servlets #Hicham Qaissi#

1

Tutorial J2EE Servlets

Hicham Qaissi

[email protected]

Page 2: J2EE Servlets Tutorial

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

Page 3: J2EE Servlets Tutorial

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

Page 4: J2EE Servlets Tutorial

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

Page 5: J2EE Servlets Tutorial

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&param2=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.

Page 6: J2EE Servlets Tutorial

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;

Page 7: J2EE Servlets Tutorial

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

Page 8: J2EE Servlets Tutorial

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” > …

Page 9: J2EE Servlets Tutorial

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.

Page 10: J2EE Servlets Tutorial

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.

Page 11: J2EE Servlets Tutorial

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.

Page 12: J2EE Servlets Tutorial

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();

Page 13: J2EE Servlets Tutorial

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)

Page 14: J2EE Servlets Tutorial

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.

Page 15: J2EE Servlets Tutorial

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.

Page 16: J2EE Servlets Tutorial

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.

Page 17: J2EE Servlets Tutorial

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.

Page 18: J2EE Servlets Tutorial

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:

Page 19: J2EE Servlets Tutorial

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;

Page 20: J2EE Servlets Tutorial

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 );

Page 21: J2EE Servlets Tutorial

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);

Page 22: J2EE Servlets Tutorial

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.

Page 23: J2EE Servlets Tutorial

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.

Page 24: J2EE Servlets Tutorial

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();

Page 25: J2EE Servlets Tutorial

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.

Page 26: J2EE Servlets Tutorial

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:

Page 27: J2EE Servlets Tutorial

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:

Page 28: J2EE Servlets Tutorial

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;

Page 29: J2EE Servlets Tutorial

Tutorial J2EE Servlets #Hicham Qaissi#

29

���� ��