模拟JavaWeb过滤器——责任链模式

来源:互联网 发布:有什么好用的水乳 知乎 编辑:程序博客网 时间:2024/06/05 14:59

对request和response里的字符串信息过滤(在这里我们通过过滤器来达到对request和response传入的数据替换一些字和增加一些字的效果),

在过滤器层面上模拟客户端和服务器交互,如下图:























这里我们直接对request和response的成员变量赋值来代替客户端和服务器的操作(测试内容)。重点关注Filter的实现。需要注意的是我们为了模仿现实的客户端和服务器交互,

request是先通过HTMLFilter再通过SensitiveFilter过滤才能到达服务器,而response与它相反,是先通过SensitiveFilter再通过HTMLFilter过滤器过滤才能返回服务端,

就像栈一样“先进后出”,这是我们重点要考虑的问题。


第一步我们新建一个包来存放model类(这里是Request类和Response类)。

可以参考一下我的包结构











在model包下面新建Request类和Response类。分别都只含有一个String类型的成员变量,我们接下来的工作就是对这两个数据操作。

Request.java

package com.zby.dp.model;public class Request {private String requestStr;public String getRequestStr() {return requestStr;}public void setRequestStr(String requestStr) {this.requestStr = requestStr;}}
package com.zby.dp.model;
public class Response {private String responseStr;public String getResponseStr() {return responseStr;}public void setResponseStr(String responseStr) {this.responseStr = responseStr;}}



第二步,新建一个包来存放filter过滤器。

我们这里需要用到HTMLFilter过滤器和SensitiveFilter过滤器这两个过滤器,但是为了增加程序的拓展性,我们在这里定义一个IFilter接口,使所有过滤器都实现这个接口,接口里面定义了一个过滤方法。

package com.zby.dp.filter;import com.zby.dp.model.Request;import com.zby.dp.model.Response;public interface IFilter {void doFilter(Request request,Response response,FilterChain filterChain);}
接下来我们要定义一个过滤器链,来达到批量使用过滤器和达到前面所提到的过滤器“先进后出”的效果。
package com.zby.dp.filter;import java.util.ArrayList;import java.util.List;import com.zby.dp.model.Request;import com.zby.dp.model.Response;public class FilterChain {private List<IFilter> filters = new ArrayList<IFilter>();//存放过滤器的有序集合private int index;//index是关键,由它确定了执行哪一个过滤器public List<IFilter> getFilters() {return filters;}public void setFilters(List<IFilter> filters) {this.filters = filters;}public FilterChain addFilter(IFilter filter){filters.add(filter);//对Filter集合添加新的过滤器return this;//这里返回this这个FilterChain类型,/*是为了方便可以filterChain.addFilter(XXX).addFilter(XXX). ... 这样一直点下去当然也可以把方法设为void,方法体里面只有add语句。*/}public void doFilter(Request request,Response response,FilterChain filterChain){if (index == filters.size()) {return;/*当index第一次等于过滤器大小的时候,就相当于requestStr已经通过所有过滤器,即将传入服务器了*/}IFilter filter= filters.get(index);//得到当前过滤器index++;//指定下一个过滤器filter.doFilter(request, response, filterChain);//调用当前过滤器的对String操作的方法}}
下面新建HTMLFilter过滤器和SensitiveFilter过滤器实现IFilter接口:

HTMLFilter.java

package com.zby.dp.filter;import com.zby.dp.model.Request;import com.zby.dp.model.Response;public class HTMLFilter implements IFilter {@Overridepublic void doFilter(Request request, Response response,FilterChain filterChain) {// TODO Auto-generated method stub/*首先对客户端传来的Request里的requestStr进行符号替换和增加字符操作。 * 这里的------------HTMLFilter----request作为执行的标志*/request.setRequestStr(request.getRequestStr().replace('<', '[').replace('>', ']')+"------------HTMLFilter----request");//执行完request再交给FilterChain分配下一步过滤filterChain.doFilter(request, response, filterChain);//上面方法返回时才调用此方法,达到栈的先进后出的效果response.setResponseStr(response.getResponseStr()+"------------HTMLFilter----response");}}

SensitiveFilter类同上
package com.zby.dp.filter;import com.zby.dp.model.Request;import com.zby.dp.model.Response;public class SensitiveFilter implements IFilter {@Overridepublic void doFilter(Request request, Response response,FilterChain filterChain) {// TODO Auto-generated method stubrequest.setRequestStr(request.getRequestStr().replace("和谐词", "XXX")+"------------SensitiveFilter----request");filterChain.doFilter(request, response, filterChain);response.setResponseStr(response.getResponseStr()+"------------SensitiveFilter----response");}}

到这里我们模拟的javaWeb过滤器就实现了,我们可以开始测试了:
首先,我们新建一个存放测试类的包。然后在包下面定义一个Test类。
package com.zby.dp.test;import com.zby.dp.filter.FilterChain;import com.zby.dp.filter.HTMLFilter;import com.zby.dp.filter.SensitiveFilter;import com.zby.dp.model.Request;import com.zby.dp.model.Response;public class Test {public static void main(String[] args) {//模拟客户端和服务器输入和返回的值String requestStr = "<I am request!这里有和谐词>";String responseStr = "I am response!";//添加所需过滤器到filterChain里的List集合,供程序使用FilterChain filterChain = new FilterChain();filterChain.addFilter(new HTMLFilter()).addFilter(new SensitiveFilter());//传入参数到request和response对象Request request = new Request();request.setRequestStr(requestStr);Response response = new Response();response.setResponseStr(responseStr);//执行过滤方法filterChain.doFilter(request, response, filterChain);//打印出request和response对象里的成员变量的值System.out.println(request.getRequestStr());System.out.println(response.getResponseStr());}}

运行结果:[I am request!这里有XXX]------------HTMLFilter----request------------SensitiveFilter----requestI am response!------------SensitiveFilter----response------------HTMLFilter----response

温馨提示:在main方法里的filterChain.doFilter(request, response, filterChain);添加断点,进行单步调试,可以很清晰的看到程序步骤、调用关系和变量值的变化。






0 0
原创粉丝点击