紧接着上一个问题来:
为了不要跟原来的代码冲突,又新建了一个工程,将所有代码放在一起。
代码清单:(为了测试简洁,去掉了FaceFilter.java)
Filter.java
FilterChain.java
HTMLFilter.java
Main.java
MsgProcessor.java
Request.java
Response.java
SesitiveFilter.java
因为新加入了Response和Request类,我们要改写几个类:
改写Filter.java:
参数该成request和response
改写FilterChian:
具体的各种Filter我们就应该这么做了(先处理request请求):
HTMLFilter:
HTMLFilter:
如果我们既想处理request又想处理response,处理反馈这种东西,应该在所有请求处理完毕之后,
再来处理我们这个反馈。因为我们反馈的信息肯定是根据请求最后处理的结果来决定的。
我们先删除掉MsgProcessor.java(因为现在这个类有些多余,不如将东西都放在Main类中去做)
在Main中:
大家好:),[script],和谐,帮助,我们要把设计模式学好
response
现在我们只处理了request的信息,还没有处理response的信息
对于request和response我们要求的顺序是这样的:
当我们的一个request传过来的时候,被第一个Filter处理,接下来被第二、第三个Filter处理,
处理完成之后,会有response对象从服务器端反馈信息给我,这个反馈信息被处理的过程是,首先
被第三个进行处理,接下来被第二个处理,最后被第一个处理(有些像堆栈)。
上面说的实现起来要需要一些技巧。
我们先给HTMLFilter和SesitiveFilter类的request和response处理分别加上标记,
来观察一下过滤链的运行顺序:
HTMLFilter:
SesitiveFilter:
大家好:),[script],和谐,帮助,我们要把设计模式学好----HTMLFilter----SesitiveFilter
response----HTMLFilter----SesitiveFilter
对于request请求这个过滤顺序是对的,但是对于response这个过滤顺序就不是刚刚我们所说的想要的
那种顺序,说明我们不可以在处理request的下面去直接处理response。想要完成这个功能,就需要一些扎实的编程技巧。
我们在Filter接口的doFilter方法中加入FilterChain的参数,这样一来,我们就可以在doFilter方法
中去控制使用FilterChain中各种Filter的顺序了。
Filter:
其他各类加上此参数即可。
当我们处理完request信息之后,我可以拿FilterChain使用。
要改写一下FilterChain,好让它能去主动一个一个调用Filter,而不是像之前
的一次遍历着去处理信息:
处理完request之后我们马上让FilterChain去调用下一个Filter:
我们来测试Main,测试结果为:
大家好:),[script],和谐,帮助,我们要把设计模式学好----HTMLFilter----SesitiveFilter
response----SesitiveFilter----HTMLFilter
刚好达到我们想要的结果,使response的处理是逆向的(request是从栈顶到站底,response是从栈底到栈顶)!
大家可能还没摸清头脑,我们分析一下:
看Main:
其实运行一下,仔细思考一下(前提是你理解递归的概念),理解起来并不难。难得的是,JavaWeb中对Servlet的过滤器就是采用类似这种机制来完成请求和反馈的过滤的(其实还不如刚刚我们设计的那种)。
至此责任链就探讨完了,大家是不是也理解了Filter的一些原理?
在此感谢马士兵老师的"设计模式"视频的讲解。
转载请注明出处:http://blog.csdn.net/acmman/article/details/44673483
为了不要跟原来的代码冲突,又新建了一个工程,将所有代码放在一起。
代码清单:(为了测试简洁,去掉了FaceFilter.java)
Filter.java
FilterChain.java
HTMLFilter.java
Main.java
MsgProcessor.java
Request.java
Response.java
SesitiveFilter.java
因为新加入了Response和Request类,我们要改写几个类:
改写Filter.java:
package cn.edu.hpu.filter.web;
public interface Filter {
void doFilter(Request request,Response response);
}
参数该成request和response
改写FilterChian:
package cn.edu.hpu.filter.web;
import java.util.List;
import java.util.ArrayList;
public class FilterChain implements Filter{
List<Filter> filters=new ArrayList<Filter>();
//返回值是FilterChain只为了在Main中满足链条式的编程
public FilterChain addFilter(Filter f) {
this.filters.add(f);
return this;
}
@Override
public void doFilter(Request request,Response response) {
for(Filter f:filters){
f.doFilter(request,response);
}
}
}
具体的各种Filter我们就应该这么做了(先处理request请求):
HTMLFilter:
package cn.edu.hpu.filter.web;
public class SesitiveFilter implements Filter {
@Override
public void doFilter(Request request, Response response) {
String r=request.getRequestStr().replace("偷盗", "和谐")
.replace("抢劫", "帮助");
request.setRequestStr(r);
}
}
HTMLFilter:
package cn.edu.hpu.filter.web;
public class HTMLFilter implements Filter {
@Override
public void doFilter(Request request, Response response) {
//先处理带尖括号的信息
String str=request.getRequestStr().replace('<', '[')
.replace('>', ']');
request.setRequestStr(str);
}
}
如果我们既想处理request又想处理response,处理反馈这种东西,应该在所有请求处理完毕之后,
再来处理我们这个反馈。因为我们反馈的信息肯定是根据请求最后处理的结果来决定的。
我们先删除掉MsgProcessor.java(因为现在这个类有些多余,不如将东西都放在Main类中去做)
在Main中:
package cn.edu.hpu.filter.web;
public class Main {
public static void main(String[] args) {
String msg="大家好:),<script>,偷盗,抢劫,我们要把设计模式学好";
Request request=new Request();
request.setRequestStr(msg);
Response response=new Response();
//response对象无反馈信息之前先设一个暂时的信息"response"
response.setResponseStr("response");
FilterChain fc=new FilterChain();
fc.addFilter(new HTMLFilter())
.addFilter(new SesitiveFilter());//链条式写法
fc.doFilter(request, response);
System.out.println(request.getRequestStr());
System.out.println(response.getResponseStr());
}
}
测试结果:
大家好:),[script],和谐,帮助,我们要把设计模式学好
response
现在我们只处理了request的信息,还没有处理response的信息
对于request和response我们要求的顺序是这样的:
当我们的一个request传过来的时候,被第一个Filter处理,接下来被第二、第三个Filter处理,
处理完成之后,会有response对象从服务器端反馈信息给我,这个反馈信息被处理的过程是,首先
被第三个进行处理,接下来被第二个处理,最后被第一个处理(有些像堆栈)。
上面说的实现起来要需要一些技巧。
我们先给HTMLFilter和SesitiveFilter类的request和response处理分别加上标记,
来观察一下过滤链的运行顺序:
HTMLFilter:
package cn.edu.hpu.filter.web;
public class HTMLFilter implements Filter {
@Override
public void doFilter(Request request, Response response) {
//先处理带尖括号的信息
String str=request.getRequestStr().replace('<', '[')
.replace('>', ']');
request.setRequestStr(str+"----HTMLFilter");
str=response.getResponseStr()+"----HTMLFilter";
response.setResponseStr(str);
}
}
SesitiveFilter:
package cn.edu.hpu.filter.web;
public class SesitiveFilter implements Filter {
@Override
public void doFilter(Request request, Response response) {
String r=request.getRequestStr().replace("偷盗", "和谐")
.replace("抢劫", "帮助");
request.setRequestStr(r+"----SesitiveFilter");
r=response.getResponseStr()+"----SesitiveFilter";
response.setResponseStr(r);
}
}
Main的测试结果:
大家好:),[script],和谐,帮助,我们要把设计模式学好----HTMLFilter----SesitiveFilter
response----HTMLFilter----SesitiveFilter
对于request请求这个过滤顺序是对的,但是对于response这个过滤顺序就不是刚刚我们所说的想要的
那种顺序,说明我们不可以在处理request的下面去直接处理response。想要完成这个功能,就需要一些扎实的编程技巧。
我们在Filter接口的doFilter方法中加入FilterChain的参数,这样一来,我们就可以在doFilter方法
中去控制使用FilterChain中各种Filter的顺序了。
Filter:
package cn.edu.hpu.filter.web;
public interface Filter {
void doFilter(Request request,Response response,FilterChain fc);
}
其他各类加上此参数即可。
当我们处理完request信息之后,我可以拿FilterChain使用。
要改写一下FilterChain,好让它能去主动一个一个调用Filter,而不是像之前
的一次遍历着去处理信息:
package cn.edu.hpu.filter.web;
import java.util.List;
import java.util.ArrayList;
public class FilterChain implements Filter{
List<Filter> filters=new ArrayList<Filter>();
//记录运行到哪一个Filter了
int index=0;
//返回值是FilterChain只为了在Main中满足链条式的编程
public FilterChain addFilter(Filter f) {
this.filters.add(f);
return this;
}
@Override
public void doFilter(Request request,Response response,FilterChain fc) {
if(index==filters.size()) return;
Filter f=filters.get(index);
index++;
f.doFilter(request, response, fc);
}
}
处理完request之后我们马上让FilterChain去调用下一个Filter:
package cn.edu.hpu.filter.web;
public class SesitiveFilter implements Filter {
@Override
public void doFilter(Request request, Response response,FilterChain fc) {
String r=request.getRequestStr().replace("偷盗", "和谐")
.replace("抢劫", "帮助");
request.setRequestStr(r+"----SesitiveFilter");
fc.doFilter(request, response, fc);
r=response.getResponseStr()+"----SesitiveFilter";
response.setResponseStr(r);
}
}
package cn.edu.hpu.filter.web;
public class HTMLFilter implements Filter {
@Override
public void doFilter(Request request, Response response,FilterChain fc) {
//先处理带尖括号的信息
String str=request.getRequestStr().replace('<', '[')
.replace('>', ']');
request.setRequestStr(str+"----HTMLFilter");
fc.doFilter(request, response, fc);
str=response.getResponseStr()+"----HTMLFilter";
response.setResponseStr(str);
}
}
我们来测试Main,测试结果为:
大家好:),[script],和谐,帮助,我们要把设计模式学好----HTMLFilter----SesitiveFilter
response----SesitiveFilter----HTMLFilter
刚好达到我们想要的结果,使response的处理是逆向的(request是从栈顶到站底,response是从栈底到栈顶)!
大家可能还没摸清头脑,我们分析一下:
看Main:
package cn.edu.hpu.filter.web;
public class Main {
public static void main(String[] args) {
String msg="大家好:),<script>,偷盗,抢劫,我们要把设计模式学好";
Request request=new Request();
request.setRequestStr(msg);
Response response=new Response();
//response对象无反馈信息之前先设一个暂时的信息"response"
response.setResponseStr("response");
FilterChain fc=new FilterChain();
fc.addFilter(new HTMLFilter())
.addFilter(new SesitiveFilter());//链条式写法
fc.doFilter(request, response,fc);
System.out.println(request.getRequestStr());
System.out.println(response.getResponseStr());
}
}
我们首先调用的是FilterChain的doFilter方法,这个时候,FilterChain中的index是0,也就是说调用了第一个Filter即HTMLFilter,这个时候在HTMLFilter中处理了request的信息之后(此时是request信息被第一次处理,并且加了标记"----HTMLFilter"),调用了FilterChain的doFilter方法,此时在FilterChain的doFilter方法中又进一步调用了下一个Filter,这样下来,最终调取了最后的SesitiveFilter,在SesitiveFilter中进一步处理了request的信息(此时是request信息被第二次处理,并且加了标记"----SesitiveFilter"),然后继续执行FilterChain的doFilter方法,发现index已经到头了,方法结束,这个时候开始执行下面的处理Response的代码(此时response信息被第一次处理,并且加了标记"----SesitiveFilter"),处理完毕时候跳出了递归,最后又回到了HTMLFilter中,接下去处理response(此时response信息被第二次处理,并且加了标记"----HTMLFilter"),
其实运行一下,仔细思考一下(前提是你理解递归的概念),理解起来并不难。难得的是,JavaWeb中对Servlet的过滤器就是采用类似这种机制来完成请求和反馈的过滤的(其实还不如刚刚我们设计的那种)。
至此责任链就探讨完了,大家是不是也理解了Filter的一些原理?
在此感谢马士兵老师的"设计模式"视频的讲解。
转载请注明出处:http://blog.csdn.net/acmman/article/details/44673483