Successfully reported this slideshow.

J2EE Servlets Tutorial

6,542 views

Published on

Un tutorial bastante completo de la API J2EE Servlets.

Published in: Technology

J2EE Servlets Tutorial

  1. 1. 1 Tutorial J2EE Servlets Hicham Qaissi hicham.qaissi@gmail.com Tutorial J2EE Servlets #Hicham Qaissi#
  2. 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 2 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. 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 3 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. 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. 4 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: public void service(ServletRequest req, ServletResponse res) Petición HTTP Servlet public void service(HttpServletRequest req, HttpServletResponse res) Respuesta HTTP public void doXXX(HttpServletRequest req, HttpServletResponse res) 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. Tutorial J2EE Servlets #Hicham Qaissi#
  5. 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.). 5 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. Tutorial J2EE Servlets #Hicham Qaissi#
  6. 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. 6 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, HttpServletResponse 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, HttpServletResponse res) throws ServletException, IOException; protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException; protected void doHead(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException; protected void doOptions(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException; protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException; protected void doPut(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException; protected void doTrace(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException; Tutorial J2EE Servlets #Hicham Qaissi#
  7. 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 7 de despliegue (web.xml) de la aplicación Web por medio del objeto ServletConfig pasado como parámetro. Public void init(ServletConfig config) throws ServletException; 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, ServletResponse 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, HttpServletResponse 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. 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: 8 • 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, HttpServletException 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étodo 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. 9. 6. Configuración del Servlet: La interfaz ServletConfig 9 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. 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(); 10 • 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, HttpServletResponse 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. 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 11 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(“nombre”); 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 objeto); 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. 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 provienen de controles HTML, como // un conjunto de casillas de verificación <CHECKBOX>, una lista de selección // múltiple <SELECT> o un conjunto de valores que lleven el mismo nombre public java.util.Enumeration getParameterValues (String 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 12 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 objeto); 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 java.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 java.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. 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(); 13 • 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. 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); 14 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.getOutputStream(); 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. 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 15 respuesta al cliente, con lo cual no puede enviarse ningún otro dato. public void flushBuffer() throws java.io.IOException • 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. 16. public void sendError(int sc) throws java.io.IOException; 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 16 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. 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 17 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, HttpServletResponse 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. 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.*; 18 public class MiFiltro implements Filter{ private FilterConfig filterConfig = null; public void init(FilterConfig filterConfig) throws ServletException{ this.filterConfig = filterConfig; … } public void doFilter(ServletRequest req, ServletResponse 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. 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 19 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, ServletResponse 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-class> <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: ” + filterConfiggetFilterName()); mode = filterConfig.getInitParameter(“modo”); if(mode == null || !mode.equalsIgboreCase(“simple”) || !mode.equalsIgnoreCase(“detallado”)) mode = “simple”; log(“modo de registro: ” + mode); } public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException{ HttpServletRequest httpReq = (HttpServletRequest)req; Tutorial J2EE Servlets #Hicham Qaissi#
  20. 20. log(“*** Ha entrado una petición”); chain.doFilter(req, res);//saltar al siguiente Filtro } public void destroy(){ log(“Destrucción del filtro: ” + filterConfig.getFilterName()); filterConfig = null; } private void log(“String message”){ context.log(message); } } 20 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. 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: 21 • public void attributeAdded(ServletContextAttrinuteEvent scab); • public void attributeReplaced(ServletContextAttrinuteEvent scab); • public void attributeRemoved(ServletContextAttrinuteEvent 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 hse); • 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(HttpSessionBindingEvent hsbe); Tutorial J2EE Servlets #Hicham Qaissi#
  22. 22. • public void attributeRemoved(HttpSessionBindingEvent 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>. … 22 <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. 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); 23 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, HttpServletResponse res) throws ServletException, IOException{ … Cookie cookie1 = new Cookie(“KeyCookie1”, “valCookie1”); Cookie cookie2 = new Cookie(“KeyCookie2”, “valCookie2”); … 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. 24. public Cookie[] getCookies(); Ejemplo de manipulación: public void doXXX(HttpServletRequest req, HttpServletResponse 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()); } } 24 … } 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 devuelve una nueva si la //petición (HttpServletRequest) no contiene id de sesió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 objet); • public Objectt getObject(String name); • public java.util.Enumeration getAttributeNames(); • public void removeAttribute(); • public Boolean isNew(); Tutorial J2EE Servlets #Hicham Qaissi#
  25. 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 milisegundos Método que devuelve una referencia del contexto de aplicación Web al que está asociada 25 la sesión actual: • public ServletContext getServletContext() Ejemplo de manipulación: public void doXXX(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException{ … // recuperación de la session HttpSession session = req.getSession(); // si no es nueva, se destruye y se crea una nueva 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 atributos 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. 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 26 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(“/MiWebApp/servlet/MiServlet”) + “”>”); Ejemplo para URL de redirección: Tutorial J2EE Servlets #Hicham Qaissi#
  27. 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: 27 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, ServletResponse response) throws ServletException, IOException; Ejemplo: Tutorial J2EE Servlets #Hicham Qaissi#
  28. 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í 28 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, ServletResponse response) throws ServletException, IOException; Tutorial J2EE Servlets #Hicham Qaissi#
  29. 29. 29 Tutorial J2EE Servlets #Hicham Qaissi#

×