J2EE表现层模式-拦截过滤器
问题:
要在请求被处理之前和之后拦截并操作一个请求和它的响应。
所谓请求的预处理就和后处理,是指在请求的核心处理操作之前、之后进行的操作。这之中有些操作决定了处理过程是否还要继续,另一些则把输入、输出数据转化成合适进一步处理的形式。比如:
客户端是否是一个有效的会话?
请求的目标路径是否违反了限制条件?
系统是否支持客户端的浏览器类型?
客户端是使用哪一种编码格式发送数据的?
请求数据流是否加密?是否压缩?
对于这些以及更多的请求处理过程,一种常见的处理思路使用是用一长串的条件检查思路实现,通常会有嵌套的控制语句来控制执行流程。但是,既然在每个处理语句中执行的都是相似的操作,就会生成很多重复的代码。这样进行预处理和后处理导致代码质量脆弱、满是复制粘贴风格的程序,因为控制流程以及特定的处理操作都和应用逻辑混在了一起。而且,这样的做法还会加大预处理/后处理组件与核心应用处理代码之间的耦合。
约束:
--要在多个请求之间实现集中、通用的处理,比如检查每个请求的数据编码方式、为每个请求留下日志信息或压缩输出反映。
--要在预处理/后处理组件与请求处理核心服务之间实现松耦合,这样再加入/删除预处理/后处理操作就很容易,不会干扰核心服务。
--要使预处理/后处理之间相互独立,每个组件都能自足存在,从而增进重用。
解决方案:
使用拦截过滤器,作为一个可插拔的过滤器,实现请求、响应的预处理和后处理。另有一个过滤器管理器,负责吧各个处于松耦合关系的过滤器结合成一个链,并把控制依次委派给合适的过滤器。这样一来,不必改动现有代码就能够以各种方式加入、删除、合并这些过滤器。
就像其他各种系统中一样,如果系统中存在大量重复任务,就应该找到重复的操作,提取出来,并且使他的粒度变得足够粗,以便能够多出使用。这就是可插拔式过滤器的作用。
这样就可以给主要处理过程加入各种常见的服务,比如日志、调试等等。过滤器独立于主要的应用逻辑的代码,所以就可以通过声明部署加入或者删除过滤器。
通过部署描述符中的声明来控制过滤器,正如“servlet技术规范”2.3版中描述的一样。“servlet技术规范”中包括了一种标准机制,可以来构造过滤器链,并且可以从链中加入和删除过滤器而不会干扰核心服务。部署配置文件构造了一个过滤器链,并且可以把特定的URL映射到这个过滤器链上。当客户端请求的资源符合配置中被映射的URL时,链中的过滤器,就在系统处理该请求的目标资源之前<预处理>和/或之后别调用了。
策略:
标准过滤器策略
定制过滤器策略
基本过滤器策略
模板过滤器策略
web Service 消息处理策略
定制SOAP过滤器策略
JAX-RPC过滤器策略
效果:
--利用松耦合的处理器实现控制集中化
--增进了重用
--能够灵活的通过声明配置
--不便于信息共享