Intercepting Filter
Contexto
El mecanismo de manejo de peticiones de la capa de presentación recibe muchos tipos diferentes de peticiones, cada uno de los cuales requiere varios tipos de procesamiento. Algunas peticiones simplemente requieren su reenvió al componente manejador apropiado, mientras que otras peticiones deben ser modificadas, auditadas, o descomprimidas antes de su procesamiento posterior.
Problema
Se requiere un pre-procesamiento y un post-procesamiento de unas peticiones o respuestas de un cliente Web.
Cuando una petición entra a una aplicación Web, normalmente debe pasar varios test de entrada antes del estado de procesamiento principal. Por ejemplo,
¿Se ha autentificado el cliente?
¿Tiene el cliente una sesión válida?
¿La dirección IP del cliente es de una red conocida?
¿Viola alguna restricción el path de la petición?
¿Qué codificación usa el cliente para enviar los datos?
¿Soportamos el tipo de navegador del cliente?
Algunos de estos chequeos son tests, que resultan en una respuesta de si o no que determina si continuará el procesamiento. Otros chequeos manipulan el stream de datos entrantes a una forma aceptable para el procesamiento.
La solución básica consiste en un serie de chequeos condicionales, si cualquiera de ellos falla la petición se aborta. Las sentencias if/else anidadas son una estrategia estándar, pero esta solución tiene fragilidad de código y un estilo de programación de copiar-y-pegar, porque el flujo del filtrado y la acción de los filtros se compila dentro de la aplicación.
La clave para solventar este problema de una forma flexible y no obstrusiva es tener un mecanismo simple para añadir y eliminar componentes de procesamiento, en el que cada componente completa una acción de filtrado específica.
Causas
Procesamiento común, como un chequeo del esquema de codificación de datos o la información de login de cada petición, completo por cada petición.
Se desea la centralización de la lógica común.
Se debería facilitar la adición o eliminación de sevicios sin afectar a los componentes existentes, para que se puedan utilizar en gran variedad de combinaciones, como
Logging y autentificación.
Depuración y transformación de la salida para un cliente específico
Descomprensión y conversión del esquema de codificación de la entrada.
Solución
Crear filtros conectables para procesar servicios comunes de una forma estándar sin requerir cambios en el código principal del procesamiento de la petición. Los filtros interceptan las peticiones entrantes y las respuestas salientes, permitiendo un pre y post-procesamiento. Podemos añadir y eliminar estos filtros a discrección, sin necesitar cambios en nuestro código existente.
Podemos, en efecto, decorar nuestro procesamiento principal con una veriedad de servicios comunes, como la seguridad, el logging, el depurado, etc. Estos filtros son componentes independientes del código de la aplicación principal, y pueden añadirse o eliminarse de forma declarativa. Por ejemplo, se podría modificar un fichero de configuración de despliegue para configurar una cadena de filtros. Cuando un cliente pide un recurso que corresponde con este mapeo de URL configurado, se procesa cada filtro de la cadena antes de poder invocar el recurso objetivo.
Estructura
La siguiente figura representa el diagrama de clases del patrón Intercepting Filter.
Participantes y Responsabilidades
La siguiente figura representa el diagrama de la secuencia del patrón Intercepting Filter.
FilterManager
- El FilterManager maneja el procesamiento de filtros. Crea el FilterChain con los filtros apropiados, en el orden correcto e inicia el procesamiento.
FilterChain
- El FilterChain es una collection ordenada de filtros indenpendientes.
FilterOne, FilterTwo, FilterThree
- Estos son los filtros individuales que son mapeados a un objetivo. El FilterChain coordina su procesamiento.
Target
- El Target es el recurso que el cliente ha solicitado.
Estrategias
Custom Filter
El filtro se implementa mediante una estrategia personalizada definida por el desarrollador. Esto es menos flexible y menos poderoso que la preferida Estrategia de Filtro Estándar que veremos en la siguiente sección y que sólo está disponible en contenedores que soporten la especificación servlet 2.3. La estrategia de filtro personalizado es menos poderosa porque no puede proporcionar una envoltura para los objetos request y response de una forma estándar y portable. Además, el objeto request no se puede modificar, y se debe introducir alguna suerte de mecanismo de buffer si los filtros son para controlar los streams de salida. Para implementar esta estrategia, el desarrollador podría utilizar el patrón Decorator [GoF] para envolver los filtros alrededor de la lógica principal del procesamiento de la petición. Por ejemplo, podría haber un filtro de depuración que envuelva un filtro de autentificación. Los siguientes fragmentos de código muestran como se podrían crear estos mecanismos de forma programátia:
DebuggingFilter:
public class DebuggingFilter implements Processor {
private Processor
target;
public
DebuggingFilter(Processor myTarget) {
target = myTarget;
}
public void
execute(ServletRequest req,
ServletResponse res)
throws IOException,
ServletException {
//Do some filter processing here, such as
// displaying request parameters
target.execute(req, res);
}
}
CoreProcessor:
public class CoreProcessor implements Processor {
private Processor
target;
public
CoreProcessor() {
this(null);
}
public
CoreProcessor(Processor myTarget) {
target = myTarget;
}
public void
execute(ServletRequest req,
ServletResponse
res) throws IOException,
ServletException {
//Do core
processing here
}
}
En el controlador servlet, hemos delegado en un método
llamado processRequest para manejar las peticiones entrantes:
public void processRequest(ServletRequest req,
ServletResponse res)
throws IOException,
ServletException {
Processor processors
= new DebuggingFilter(
new
AuthenticationFilter(new CoreProcessor()));
processors.execute(req, res);
//Then dispatch to
next resource, which is probably
// the View to
display
dispatcher.dispatch(req, res);
}
Consecuencias
Centraliza el Control con Controladores de Acoplamiento Ligero
- Los filtros proporcionan un lugar centralaizado para controlar el procesamiento a través de múltiples peticiones, como lo hace el controlador. Los filtros están mejor preparados para manejar las peticiones y respuestas para el control último por un recurso objetivo, como un controlador. Además, un controlador frecuentemente junta el control de numerosos sevicios comunes y no relacionados, como la autentificación, el login, la encriptación, etc., mientras que los filtros nos permiten controladores de acoplamiento más ligero, que se pueden combinar.
Mejora la Reutilización
- Los filtros promueven la limpieza del particionamiento de la aplicación y aconsejan su reutilización. Estos interceptores conectables se añaden y eliminan al código existente de forma transparente y debido a su interface estándar, funcionan en cualquier combinación y son reutilizables por varias presentaciones.
Configuración Declarativa y Flexible
- Se pueden combinar numerosos servicios en varias permutaciones sin tener que recompilar ni una sola vez el código fuente.
La Compartición Información es Ineficiente
- Compartir información entre filtros puede ser ineficiente, porque por definición todo filtro tiene acoplamiento ligero. Si se deben compartir grandes cantidades de información entre los filtros, esta aproximación podría ser muy costosa.
Patrones Relacionados
Front Controller
- El controlador resuelve algunos problemas similares, pero está mejor diseñado para manejar el procesamiento principal.
Decorator [GoF]
- El patrón Intercepting Filter está relacionado con el patrón Decorator, que proporciona envolturas conectables dinámicamente.
Template Method [GoF]
- El patrón de Plantillas de Métodos se utiliza para implementar la Estrategia de Plantilla de Filtros.
Interceptor [POSA2]
- El patrón Intercepting Filter está relacionado con el patron Interceptor, que permite que se pueden añadir servicios de forma transparente y dispararlos automáticamente.
Pipes and Filters [POSA1]
- El patrón Intercepting Filter está relacionado con el patrón Pipes and Filters.
Referencias
http://programacion.net/articulo/catalogo_de_patrones_de_diseno_j2ee_i_-_capa_de_presentacion_240/3
No hay comentarios:
Publicar un comentario