所谓装饰者模式(decorator -pattern)动态的给对象添加职责。装饰者较被装饰者拥有更多的功能,且除本身的功能外还可以调用被装饰者的功能。
比较常见的例子是Java I/O 装饰者:
其中,各类的作用如下:
FileInputStream 作为被装饰者 提供了读取文件的基本操作
BufferedInputStream 作为装饰者,加入了额外两个功能:1 缓冲功能(改进读入大文件的性能)
2 用readLine()方法(read one line per time)增强了读入的速率
LineNumberInputStream 也是个装饰者,通过名字我们能看出其增加了计算Line Number 的 function。
好了 ,有了对装饰者模式的初步认识了,Let’s go to the theme:
What is the Filter ?
Basely Filter is a java component which used to :
1 Intercept the request coming from Client and process
2 intercept the response before arriving at Client
容器根据DD中的配置来判断Filter的invoke order 及请求的URL来具体要调用Filter。
下面是一段过滤器的配置例子:
<filter>
<filter-name>FilterRequest</filter-name>
<filter-class>com.example.web.FilterRequest</filter-class>
<init-param>
<param-name>name<param-name/>
<param-value>Bruce</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name> FilterRequest </filter-name>
<url-pattern>/filter/*.do</url-pattern>
</filter-mapping>
过滤器还可以针对具体的servlet (假设已有FilterServlet的servlet)
<filter-mapping>
<filter-name> FilterRequest </filter-name>
<servlet-name>FilterServlet</servlet-name>
</filter-mapping>
过滤器类要实现位于javax.servlet 内的Filter类,像servlet一样过滤器也有生命周期:
init() : 初始化
doFilter() : 处理过滤操作
destroy() : 删除Filter实例
看下doFilter(ServletRequest req, ServletResponse resp, FilterChain)方法
具体代码不说了,方法内利用FilterChain.doFilter(req,resp) 来完成过滤器的内联和回调。
ServletRequest 请求处理可以在该方法调用之前进行处理,那ServletResponse的处理呢?是否是在该方法调用后处理呢?
其实在在FilterChain.doFilter(req,resp)回调后 ServletResponse 已经返回客户端,再次处理已经没有意义。
此处的处理用到了装饰者类:
在FilterChain.doFilter(req,resp)方法执行之前 将 ServletResponse 类进行包装:
CompressionResponseWrapper wrapperResp = new CompressionResponseWrapper(response);
CompressionResponseWrapper 是一个包装类 ,封装了对于response的操作
只有调用FilterChain.doFilter(req, wrapperResp)
可以参照下图: