eBooks SCWCD

8 comentarios
Libros para realizar la preparación de la certificación SCWCD:







Manning SCWCD Exam Study Kit - 2nd Edition - May 2005







OReilly Head First Servlets & JSP - 2nd Edition - Mar 2008









NOTA: El libro de MANNING esta creado para la versión CX-310-081. Sin embargo, recomiendo la lectura de este libro ya que fue de mucha utilidad para mí preparación. Ciertos temas se desarrollan con mayor profundidad (aunque muy teóricos) y brindan un mayor conocimiento de fondo.

Session Management (SCWCD)

0 comentarios
Objetivos:
Section 4: Session Management
4.1- Write servlet code to store objects into a session object and retrieve objects from a session object.
4.2- Given a scenario describe the APIs used to access the session object, explain when the session object was created, and describe the mechanisms used to destroy the session object, and when it was destroyed.
4.3- Using session listeners, write code to respond to an event when an object is added to a session, and write code to respond to an event when a session object migrates from one VM to another.
4.4- Given a scenario, describe which session management mechanism the Web container could employ, how cookies might be used to manage sessions, how URL rewriting might be used to manage sessions, and write servlet code to perform URL rewriting.


Las sesiones en el protocolo HTTP
HTTP es un protocolo sin estado (stateless), cada petición al servidor web y su correspondiente respuesta es manejada como una transacción aislada. El servidor (HTTP) no tiene manera de determinar que una serie de peticiones provienen del mismo cliente.
Las sesiones, en una aplicación web, se utilizan para asociar las peticiones con el cliente. Una sesión comienza cuando un cliente desconocido envía la primera petición (que requiera crear una sesión) a la aplicación web. La misma finaliza, cuando el cliente la termina explícitamente o cuando se expira el tiempo de vida de la sesión (debido a que no se ha recibido una petición en un tiempo determinado).
La manera en que una aplicación web mantiene una sesión con el cliente es:
  • Cuando el servidor web recibe la primera petición de un cliente, el servidor inicia una sesión y le asigna un identificador único.
  • El cliente debe incluir este identificador único en cada petición subsecuente. El servidor revisa el identificador y asocia la petición con su correspondiente sesión.
Existen dos formas de implementar el soporte para sesiones, cookies y la sobreescritura de la URL.


javax.servlet.http.HttpSession
La API de servlets abstrae el concepto de sesión a través de esta interface. Cuando se inicia una sesión para un cliente, el contenedor de servlets instancia un objeto HttpSession. Los distintos servlets pueden utilizar este objeto para almacenar información relacionada al usuario y de esta manera mantener el estado del mismo. Existe un objeto HttpSession por cada sesión (o usuario). El contenedor de servlets se encarga de asociar una petición con su correspondiente objeto de sesión.
La interface javax.servlet.http.HttpServletRequest provee dos métodos para obtener la sesión:
  • HttpSession getSession (boolean create): Devuelve el correspondiente objeto sesión, o si no existe ninguna sesión y el parámetro sesión es true, crea una nueva sesión.
  • HttpSession getSession (): Método equivalente a invocar getSession (true).
Métodos de la interface HttpSession para el manejo de sus atributos:
  • void setAttribute (String name, Object value): Asocia el objeto pasado como parámetro a la sesión, y lo identifica a través del nombre.
  • Object getAttribute (String name): Devuelve el objeto asociado al nombre, o null en caso de no existir ninguno.

Manejando los eventos de sesión con las interfaces listener
En una aplicación web, cuando ocurren eventos importantes, se pueden recibir las notificaciones correspondientes a los mismos a través de las interfaces listener. Se crea una clase que implemente la interface listener correspondiente, y el contenedor de servlets invocará los métodos apropiados sobre un objeto (de esta clase) cuando ocurra algún evento.
La API de servlets define cuatro interfaces listener y dos eventos relacionados a las sesiones dentro de javax.servlet.http:
HttpSessionAttributeListener: Permite recibir notificaciones cuando se agrega, reemplaza, o elimina un atributo de un objeto HttpSession. La clase se debe especificar en el archivo web.xml. El contenedor de servlets solo crea una instancia, sobre la cual se invocaran los métodos para todas las sesiones.
  • void attributeAdded (HttpSessionBindingEvent sbe): Invocado cuando se agrega un atributo a una sesión.
  • void attributeRemoved (HttpSessionBindingEvent sbe): Invocado cuando se elimina un atributo.
  • void attributeReplaced (HttpSessionBindingEvent sbe): Invocado cuando se reemplaza un atributo.
HttpSessionBindingListener: Esta interface es implementada por aquellas clases cuyos objetos necesiten recibir notificaciones de cuando ellos son agregados y eliminados de una sesión. Esta clase no se especifica en el archivo web.xml. Cuando se agrega o elimina un objeto de una sesión, el contenedor revisa las interfaces que implementa. En caso de que el objeto implemente la interface HttpSessionBindingListener, el contenedor invoca el método correspondiente:
  • void valueBound (HttpSessionBindingEvent event): Notifica al objeto que está siendo asociado a una sesión.
  • void valueUnbound (HttpSessionBindingEvent event): Notifica al objeto que está siendo desasociado de una sesión.
HttpSessionListener: Esta interface se utiliza para recibir notificaciones de cuando una sesión se crea o se destruye. La clase que implemente dicha interface debe ser especificada en el archivo web.xml. Se crea una nueva instancia de esta clase, por cada nueva sesión creada. Posee los métodos:
  • void sessionCreated (HttpSessionEvent se): Se invoca cuando se crea una sesión.
  • void sessionDestroyed (HttpSessionEvent se): Se invoca cuando se destruye una sesión. Si dentro de este método se invoca el método getAttribute(), se lanza la excepción IllegalStateException.
HttpSessionActivationListener: (No se requiere para el examen) Esta interface se utiliza por los atributos de una sesión, para recibir notificaciones de cuando la sesión está siendo migrada a través de JVM’s en un ambiente distribuido.  De esta manera, los atributos contenidos en una sesión no se pierden, más allá de que exista más de una JVM ejecutando la aplicación. Posee los métodos:
  • void sessionDidActivate (HttpSessionEvent se): Se invoca justo después de que la sesión se activa.
  • void sessionWillPassivate (HttpSessionEvent se): Se invoca antes de desactivar la sesión.
Cerrar sesiones
La interface HttpSession provee el método:
  • void invalidate(): Cierra una sesión y desenlaza todos los objetos asociados a ella. Lanza la excepción IllegalStateException si la sesión ya ha sido cerrada.
Session timeout
El protocolo HTTP no provee ninguna señal de la terminación de una sesión en el servidor. Por este motivo, cuando el usuario no realiza ninguna acción en un período de tiempo determinado, el servidor cierra dicha sesión.
En el archivo web.xml, el elemento <session-timeout> contiene en minutos el tiempo de vida de una sesión. Un valor 0 o menor significa que la sesión nunca expirará.

    
        30
    

La interface HttpSession también posee los siguientes métodos:
  • void setMaxInactiveInterval (int seconds): Afecta solo a la sesión en la cual se invoca. Las demás, mantienen el tiempo especificado en el archivo web.xml.
  • void getMaxInactiveInterval ()
Existen dos inconsistencias entre estos modos de setear el timeout:
  1. El valor de elemento <session-timeout> se especifica en minutos, mientras que setMaxInactiveInterval() en segundos.
  2. El valor 0 o menos en el elemento <session-timeout> significa que la sesión nunca expirará, mientas que al método setMaxInactiveInterval() se le debe pasar un valor negativo (no 0) para conseguir el mismo comportamiento.

Utilización de cookies
En esta técnica, para enviar y recibir el identificador de una sesión, el contenedor de servlets utiliza los encabezados (headers) HTTP. Cuando se devuelve la respuesta, el contenedor agrega un encabezado especial que contiene el identificador de sesión. El cliente, el cual es típicamente un browser, extrae este encabezado especial, y lo almacena en la máquina local. Cuando se realiza otra petición, el cliente agrega automáticamente un encabezado que contiene el identificador de sesión almacenado. Este archivo almacenado se denomina cookie.
Cuando las cookies se encuentran deshabilitadas, el browser ignora cualquier encabezado que contenga cookies, y consecuentemente no envía ningún encabezado con cookies en la petición.


Sobreescritura de URL’s
Esta alternativa permite añadir, dentro de una respuesta, el identificador de sesión en todas las URL’s. De esta manera, cuando el usuario interactúe con el sitio, enviará automáticamente su identificador de sesión como parte de la petición.
Este mecanismo no es tranparente al desarrollador (a diferencia de las cookies). La interface HttpServletResponse provee los métodos:
  • String encodeURL (String url): Devuelve la url con el identificador de sesión adjuntado.
  • String encodeRedirectURL (String url): Idem anterior, pero se utiliza junto con el método sendRedirect().
Ambos métodos verifican si es necesario adjuntar el identificador. Si la petición contiene un encabezado de cookie, entonces las mismas están habilitadas en el browser cliente, y la sobreescritura de la url no es necesaria.
Se debe tener en cuenta que en la URL, el ID de la sesión se agrega luego del carácter ‘;’. Por ejemplo:
http://localhost:8080/scwcd/LoginServlet;jsessionid=1C9B3BAE94BE88AD45AA54B2A8AC0246?user=matias
Esto se debe a que jsessionid es parte del path info de la petición, y no es un parámetro de la misma. Este valor NO puede ser accedido a través del método HttpServletRequest.getParameter(“jsessionid”).


The Web Container Model - Filters (SCWCD)

1 comentarios
Objetivos:

Section 3: The Web Container Model (FILTERS)

3.3- Describe the Web container request processing model; write and configure a filter; create a request or response wrapper; and given a design problem, describe how to apply a filter or a wrapper.



Que es un filtro (filter)?
Para una aplicación web, un filtro es un componente web el cuál “filtra” las peticiones y respuestas que se realizan entre en cliente y el servidor. Estos filtros permiten monitorear los mensajes enviados antes de que los mismos alcancen su destino. La existencia de un filtro es transparente tanto al cliente como también al recurso (como puede ser un servlet).
También se puede emplear una cadena de filtros, en la cual los filtros se ejecutan uno seguido de otro (en cadena). Un filtro permite procesar una petición y pasarla (la petición procesada) al siguiente filtro de la cadena. Similarmente, cada filtro se ejecutará en orden inverso procesando la respuesta antes de que sea devuelta al cliente.

Como trabaja la filtración
Cuando el contenedor de servlets recibe una petición a un recurso, se verifica la existencia de filtros asociados al recurso. Si existe algún filtro asociado, el contenedor dirige la petición al filtro en vez de al recurso. Luego de que el filtro procesa la petición, realiza una de las siguientes acciones:
  • Genera la respuesta, por el mismo, y se la retorna al cliente.
  • Pasa la petición (modificada o no) al siguiente filtro de la cadena (si existe) o al recurso.
  • Dirige la petición a un recurso diferente.
Cuando se devuelve la respuesta desde el recurso, esta atraviesa el mismo conjunto de filtros en orden inverso. Cada filtro en la cadena puede modificar la respuesta.

La API de filtros (Filter API)
Interfaces del paquete javax.servlet:

javax.servlet.Filter: Todos los filtros deben implementar esta interface. Define tres métodos:
  • void init (FilterConfig) throws ServletException: El contenedor de servlets invoca este método sobre una instancia solo una vez. La implementación típica de este método es almacenar la instancia FilterConfig, para luego ser utilizada. Este método es una analogía del método init(ServletConfig) de la interface Servlet.
  • void doFilter (ServletRequest, ServletResponse, FilterChain) throws ServletException, IOException: El contenedor de servlets invoca este método para cada petición que sea mapeada con un filtro. Una implementación típica de una aplicación web, castea las instancias de ServletRequest y ServletResponse a sus correspondientes implementaciones del protocolo http, para luego realizar el procesamiento por el cual se creó el filtro. Este método es una analogía del método service(ServletRequest, ServletResponse) de la interface Servlet.
  • void destroy (): El contenedor de servlets invoca este método para liberar los recursos del filtro y realizar tareas de limpieza, antes de que el mismo sea eliminado.

javax.servlet.FilterChain: El contenedor de servlets provee una implementación para esta interface y pasa una instancia de la misma al método doFilter() del filtro. Posee solo un método:
  • void doFilter (ServletRequest, ServletResponse): Pasa la petición  al próximo componente en la cadena, otro filtro o el recurso original.

javax.servlet.FilterConfig: El contenedor de servlets provee una implementación para esta interface. Al igual que ServletConfig, la instancia se pasa a través del método init(FilterConfig). Esta interface provee métodos para acceder a los parámetros de inicialización de un filtro, y algunos otros datos:
  • String getFilterName (): Devuelve el nombre del filtro especificado en el archivo web.xml.
  • String getInitParameter (String): Devuelve el valor del parámetro especificado en el archivo web.xml.
  • Enumeration getInitParameterNames (): Devuelve una instancia Enumeration con los nombres de los parámetros de inicialización definidos en el archivo web.xml.
  • ServletContext getServletContext (): Devuelve la instancia de ServletContext asociada a la aplicación web.
Clases del paquete javax.servlet:
  • javax.servlet.ServletRequestWrapper
  • javax.servlet.ServletResponseWrapper
Clases del paquete javax.servlet.http:
  • javax.servlet.http.HttpServletRequestWapper
  • javax.servlet.http.HttpServletResponseWrapper
Estas últimas cuatro clases wrappers, funcionan de la misma manera. Toman una petición o una respuesta (ServletRequest o ServletResponse) en su constructor y delegan todas las invocaciones de métodos a ese objeto. Esto permite extender estas clases y sobrescribir cualquier método para personalizar un comportamiento.

Configurar un filtro
Para definir un filtro en el archivo web.xml, se debe utilizar los elementos <filter> y <filter-mapping>.
<!ELEMENT filter (icon?, filter-name, display-name?, description?, filter-class, init-param*) >
<!ELEMENT filter-mapping (filter-name, (url-pattern | servlet-name)) >

<filter>: Cada elemento de este tipo, introduce un nuevo filtro en la aplicación web. Este elemento puede contener varios elementos más. Algunos opcionales como: <icon>, <display-name> y <init-param>. Otros obligatorios como:
  • <filter-name>: Define el nombre del filtro dentro del archivo de configuración.
  • <filter-class>: Define la clase utilizada para instanciar el filtro.
<filter-mapping>: Al igual que <servlet-mapping>, este elemento asocia un filtro con un conjunto de URLs. Contiene los elementos:
  • <filter-name>: Identifica el filtro a asociar.
  • <url-pattern>: Se utiliza para aplicar el filtro a las peticiones que concuerden con el patrón URL.
  • <servlet-name>: Se utiliza para aplicar el filtro a todas las peticiones que se realicen al servlet asociado.
Solo puede existir un subelemento <url-pattern> o <servlet-name>, dentro un mismo <filter-mapping>.

Configurando cadenas de filtros
Las cadenas de filtros pueden ser configuradas utilizando múltiples elementos <filter-mapping>. Cuando el contenedor de servlets recibe una petición, este busca todos los mapeos de filtros que concuerdan la URI con el patrón URL. Este se considera el primer conjunto de filtros a aplicar al recurso. Luego, se buscan todos los mapeos de filtros con el nombre del servlet correspondiente. Este se convierte en el segundo conjunto de filtros en la cadena de filtros. En ambos conjuntos, el orden de los filtros se corresponde al orden de declaración de los mismos en el archivo web.xml.
El contenedor primero invoca a los filtros del primer conjunto antes que los del segundo.

Ejecución de filtros
Como la especificación de Servlets 2.4 permite invocar servlets de las siguientes maneras:
  • Como un resultado del método RequestDispatcher.forward().
  • Como un resultado del método RequestDispatcher.include().
  • En páginas de error.
Un filtro solo es invocado con peticiones entrantes (desde el cliente). Pero el archivo web.xml permite especificar los modos de invocación de un filtro:
<filter-mapping>
    <filter-name>AccessLog</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>ERROR</dispatcher>
</filter-mapping>
  • El elemento <filter-name> es obligatorio.
  • Se debe usar un elemento <url-pattern> o <servlet-name>, no se pueden usar ambos dentro de un mismo elemento <filter-mapping>.
  • Se pueden usar de 0 a 4 subelementos <dispatcher> dentro de un elemento <filter-mapping>.
  • Por defecto (si no se especifica ningún subelemento <dispatcher>) los filtros solo se aplican para peticiones entrantes a la aplicación. Es decir, solo el valor REQUEST es aplicado por defecto
  • Si el contenedor no puede encontrar el recurso solicitado por una petición, ningún filtro correspondiente a la misma se invoca. Los filtros solo se invocan si existe el recurso original.