Filter体现职责链模式
2016-07-22 15:31
351 查看
1. 前言
Filter—Filter 技术是servlet2.3 新增加的功能。完成的流程:对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。
Filter体现了一种职责琏模式。那么他是如何体现的呢?
2. 职责链模式
在具体的解释这个之前先看看职责链模式的定义:使多个对象都有机会处理请求 ,从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成一个链,并沿着这条链传递请求,直到有一个对象处理它为止。
对于Filter而言就是,请求传给具体的web资源(比如jsp/servlet)之前要经过Filter的预处理,在web资源处理完成返回给客户端之前也要被Filter处理一遍。就好比下面的这种图
当创建了多个Filter之后,客户端传来一个Request请求,它就面对着这一个Filter链,职责琏模式就体现在这里。这个请求会在这个 Filter链上一个一个被传递下去对它进行预处理,处理完成之后就传给下一个Filter直到最后一个,然后才交给web进行相应的访问和处理。它的 uml图(并不是完成的结构图,只是体现职责琏模式的结构图)如下:
一个Filter接口定义了三个方法:init()(初始化方法);destroy()(销毁方法);doFilter()(核心的职责方法);两个具体类实现了Filter接口:ConcreteFilter1和ConcreteFilter2;
一个FilterChain接口定义了一个方法:doFilter();一个具体的实现类ConcreteFilterChain;
其中FilterChain主要的作用是完成找到下一个Filter。
3. 具体的实现
下面是对于上面结构图的一个简单实现,帮助我们理解一下Filter体现的职责琏模式。
ConcreteFilter1类
package com.test.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* ConcreteFilter1类
* @author pf
*
*/
public class ConcreteFilter1 implements Filter {
// private String encoding;
@Override
public void destroy() {
System.out.println("ConcreteFilter1()的destroy()执行");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("----ConcreteFilter1()的chain.doFilter()调用之前:对用户请求(request)进行预处理");
//继续执行
//后面有filter继续调用,没有的话就进入到了jsp,一直调用最后
chain.doFilter(request, response);
System.out.println("ConcreteFilter1()的chain.doFilter()调用之后:对服务器响应(response)进行后处理");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// System.out.println("init开始");
// this.encoding = filterConfig.getInitParameter("encoding");
// System.out.println("init得到encoding:" + encoding);
System.out.println("ConcreteFilter1()的init()方法调用");
}
}
ConcreteFilter2类
package com.test.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* 采用Filter统一处理字符集
* @author pf
*
*/
public class ConcreteFilter2 implements Filter {
// private String encoding;
@Override
public void destroy() {
System.out.println("ConcreteFilter2()的destroy()执行");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("ConcreteFilter2()的chain.doFilter()调用之前");
// request.setCharacterEncoding(encoding);
//后面有filter继续调用,没有的话就进入到了jsp,一直调用最后
chain.doFilter(request, response);
System.out.println("ConcreteFilter2()的chain.doFilter()调用完成");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// System.out.println("init开始");
// this.encoding = filterConfig.getInitParameter("encoding");
// System.out.println("init得到encoding:" + encoding);
System.out.println("ConcreteFilter2()的init()方法调用");
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<filter>
<filter-name>ConcreteFilter1</filter-name>
<filter-class>com.test.filter.ConcreteFilter1</filter-class>
</filter>
<filter-mapping>
<filter-name>ConcreteFilter1</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<filter>
<filter-name>ConcreteFilter2</filter-name>
<filter-class>com.test.filter.ConcreteFilter2</filter-class>
</filter>
<filter-mapping>
<filter-name>ConcreteFilter2</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
</web-app>
完成之后启动服务器,我这里是tomcat,会显示如下信息:
说明在启动服务器的时候就会创建我们的Filter对象
随便访问一个页面再次查看console
关闭服务器:说明在关闭服务器的时候销毁创建的Filter对象
从上面的执行结果再来看一下Filter。我们设置了两个Filter,分别是ConcreteFilter1和ConcreteFilter2.按照 我们在web.xml中配置的顺序来执行,先执行了ConcreteFilter1,在执行ConcreteFilter2.
但是注意观察,他们在真正调用chain的doFilter方法之后的调用顺序正好相反了。所以我们从这个结果可以看到Filter的执行顺序是遵循”后 进先出”的原则。现将传来的url按照配置中的顺序进行预处理,但是确实先按照相反的filter顺序执行处理好的请求。
下面是讲他的调用过程画了一个时序图:
3. 总结:
通过上面代码执行的结果来看,Filter很好的实现了职责链模式,对于任何一个请求来讲都有一条Filter链可以处理它,具体是哪一个处理了我们其实并不知道但是在到达servlet之前就是已经给我们处理好了,这样子就很好的做到了对象之间的解耦和。
Filter—Filter 技术是servlet2.3 新增加的功能。完成的流程:对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。
Filter体现了一种职责琏模式。那么他是如何体现的呢?
2. 职责链模式
在具体的解释这个之前先看看职责链模式的定义:使多个对象都有机会处理请求 ,从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成一个链,并沿着这条链传递请求,直到有一个对象处理它为止。
对于Filter而言就是,请求传给具体的web资源(比如jsp/servlet)之前要经过Filter的预处理,在web资源处理完成返回给客户端之前也要被Filter处理一遍。就好比下面的这种图
当创建了多个Filter之后,客户端传来一个Request请求,它就面对着这一个Filter链,职责琏模式就体现在这里。这个请求会在这个 Filter链上一个一个被传递下去对它进行预处理,处理完成之后就传给下一个Filter直到最后一个,然后才交给web进行相应的访问和处理。它的 uml图(并不是完成的结构图,只是体现职责琏模式的结构图)如下:
一个Filter接口定义了三个方法:init()(初始化方法);destroy()(销毁方法);doFilter()(核心的职责方法);两个具体类实现了Filter接口:ConcreteFilter1和ConcreteFilter2;
一个FilterChain接口定义了一个方法:doFilter();一个具体的实现类ConcreteFilterChain;
其中FilterChain主要的作用是完成找到下一个Filter。
3. 具体的实现
下面是对于上面结构图的一个简单实现,帮助我们理解一下Filter体现的职责琏模式。
ConcreteFilter1类
package com.test.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* ConcreteFilter1类
* @author pf
*
*/
public class ConcreteFilter1 implements Filter {
// private String encoding;
@Override
public void destroy() {
System.out.println("ConcreteFilter1()的destroy()执行");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("----ConcreteFilter1()的chain.doFilter()调用之前:对用户请求(request)进行预处理");
//继续执行
//后面有filter继续调用,没有的话就进入到了jsp,一直调用最后
chain.doFilter(request, response);
System.out.println("ConcreteFilter1()的chain.doFilter()调用之后:对服务器响应(response)进行后处理");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// System.out.println("init开始");
// this.encoding = filterConfig.getInitParameter("encoding");
// System.out.println("init得到encoding:" + encoding);
System.out.println("ConcreteFilter1()的init()方法调用");
}
}
ConcreteFilter2类
package com.test.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* 采用Filter统一处理字符集
* @author pf
*
*/
public class ConcreteFilter2 implements Filter {
// private String encoding;
@Override
public void destroy() {
System.out.println("ConcreteFilter2()的destroy()执行");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("ConcreteFilter2()的chain.doFilter()调用之前");
// request.setCharacterEncoding(encoding);
//后面有filter继续调用,没有的话就进入到了jsp,一直调用最后
chain.doFilter(request, response);
System.out.println("ConcreteFilter2()的chain.doFilter()调用完成");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// System.out.println("init开始");
// this.encoding = filterConfig.getInitParameter("encoding");
// System.out.println("init得到encoding:" + encoding);
System.out.println("ConcreteFilter2()的init()方法调用");
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<filter>
<filter-name>ConcreteFilter1</filter-name>
<filter-class>com.test.filter.ConcreteFilter1</filter-class>
</filter>
<filter-mapping>
<filter-name>ConcreteFilter1</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<filter>
<filter-name>ConcreteFilter2</filter-name>
<filter-class>com.test.filter.ConcreteFilter2</filter-class>
</filter>
<filter-mapping>
<filter-name>ConcreteFilter2</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
</web-app>
完成之后启动服务器,我这里是tomcat,会显示如下信息:
说明在启动服务器的时候就会创建我们的Filter对象
随便访问一个页面再次查看console
关闭服务器:说明在关闭服务器的时候销毁创建的Filter对象
从上面的执行结果再来看一下Filter。我们设置了两个Filter,分别是ConcreteFilter1和ConcreteFilter2.按照 我们在web.xml中配置的顺序来执行,先执行了ConcreteFilter1,在执行ConcreteFilter2.
但是注意观察,他们在真正调用chain的doFilter方法之后的调用顺序正好相反了。所以我们从这个结果可以看到Filter的执行顺序是遵循”后 进先出”的原则。现将传来的url按照配置中的顺序进行预处理,但是确实先按照相反的filter顺序执行处理好的请求。
下面是讲他的调用过程画了一个时序图:
3. 总结:
通过上面代码执行的结果来看,Filter很好的实现了职责链模式,对于任何一个请求来讲都有一条Filter链可以处理它,具体是哪一个处理了我们其实并不知道但是在到达servlet之前就是已经给我们处理好了,这样子就很好的做到了对象之间的解耦和。
原文:Filter体现职责链模式
相关文章推荐
- Qt之资源系统
- WebApplicationInitializer (spring 3.x.x以上版本)
- 原码、反码、补码
- Qt之资源系统
- 使用 logback + slf4j 进行日志记录
- Qt之资源系统
- jvm 监控
- javascript Date format(js日期格式化)
- 自带bfs输出最短步数的迷宫
- 机器工作调度
- python文件路径
- Android运用手机多媒体
- Android屏幕适配不同的资源图片、布局
- Unity球形插值Slerp解析
- C# 无法加载C++编译的DLL异常
- ADC阻抗问题
- 网易实习生笔试试题 求第K大的数
- php操作memcache的步骤
- 通过贝塞尔曲线实现水波纹ProgressBar
- C++