没有合适的资源?快使用搜索试试~ 我知道了~
资源详情
资源评论
资源推荐
63 | 职责链模式(下):框架中常用的过滤器、拦截器是如何实现
的?
2020-03-27 王争
设计模式之美
进入课程
讲述:冯永吉
时长 08:25 大小 7.72M
上一节课,我们学习职责链模式的原理与实现,并且通过一个敏感词过滤框架的例子,展示
了职责链模式的设计意图。本质上来说,它跟大部分设计模式一样,都是为了解耦代码,应
对代码的复杂性,让代码满足开闭原则,提高代码的可扩展性。
除此之外,我们还提到,职责链模式常用在框架的开发中,为框架提供扩展点,让框架的使
用者在不修改框架源码的情况下,基于扩展点添加新的功能。实际上,更具体点来说,职责
链模式最常用来开发框架的过滤器和拦截器。今天,我们就通过 Servlet Filter、Spring
Interceptor 这两个 Java 开发中常用的组件,来具体讲讲它在框架开发中的应用。
话不多说,让我们正式开始今天的学习吧!
下载APP
Servlet Filter
Servlet Filter 是 Java Servlet 规范中定义的组件,翻译成中文就是过滤器,它可以实现对
HTTP 请求的过滤功能,比如鉴权、限流、记录日志、验证参数等等。因为它是 Servlet 规
范的一部分,所以,只要是支持 Servlet 的 Web 容器(比如,Tomcat、Jetty 等),都支
持过滤器功能。为了帮助你理解,我画了一张示意图阐述它的工作原理,如下所示。
在实际项目中,我们该如何使用 Servlet Filter 呢?我写了一个简单的示例代码,如下所
示。添加一个过滤器,我们只需要定义一个实现 javax.servlet.Filter 接口的过滤器类,并
且将它配置在 web.xml 配置文件中。Web 容器启动的时候,会读取 web.xml 中的配置,
创建过滤器对象。当有请求到来的时候,会先经过过滤器,然后才由 Servlet 来处理。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
public class LogFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 在创建Filter时自动调用,
// 其中filterConfig包含这个Filter的配置参数,比如name之类的(从配置文件中读取的)
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, Filte
System.out.println("拦截客户端发送来的请求.");
chain.doFilter(request, response);
System.out.println("拦截发送给客户端的响应.");
}
从刚刚的示例代码中,我们发现,添加过滤器非常方便,不需要修改任何代码,定义一个实
现 javax.servlet.Filter 的类,再改改配置就搞定了,完全符合开闭原则。那 Servlet Filter
是如何做到如此好的扩展性的呢?我想你应该已经猜到了,它利用的就是职责链模式。现
在,我们通过剖析它的源码,详细地看看它底层是如何实现的。
在上一节课中,我们讲到,职责链模式的实现包含处理器接口(IHandler)或抽象类
(Handler),以及处理器链(HandlerChain)。对应到 Servlet Filter,
javax.servlet.Filter 就是处理器接口,FilterChain 就是处理器链。接下来,我们重点来看
FilterChain 是如何实现的。
不过,我们前面也讲过,Servlet 只是一个规范,并不包含具体的实现,所以,Servlet 中
的 FilterChain 只是一个接口定义。具体的实现类由遵从 Servlet 规范的 Web 容器来提
供,比如,ApplicationFilterChain 类就是 Tomcat 提供的 FilterChain 的实现类,源码如
下所示。
为了让代码更易读懂,我对代码进行了简化,只保留了跟设计思路相关的代码片段。完整的
代码你可以自行去 Tomcat 中查看。
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@Override
public void destroy() {
// 在销毁Filter时自动调用
}
}
// 在web.xml配置文件中如下配置:
<filter>
<filter-name>logFilter</filter-name>
<filter-class>com.xzg.cd.LogFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>logFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
复制代码
1
2
3
4
5
public final class ApplicationFilterChain implements FilterChain {
private int pos = 0; //当前执行到了哪个filter
private int n; //filter的个数
private ApplicationFilterConfig[] filters;
private Servlet servlet;
剩余12页未读,继续阅读
柔粟
- 粉丝: 27
- 资源: 305
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0