对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;
}
}
我们这里需要用到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 {
@Override
public 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 {
@Override
public void doFilter(Request request, Response response,
FilterChain filterChain) {
// TODO Auto-generated method stub
request.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);添加断点,进行单步调试,可以很清晰的看到程序步骤、调用关系和变量值的变化。