今天是学习设计模式的责任链,要求如下:
模拟Java Web中的过滤器,实现对Requset消息和Response消息的过滤,且对Response消息的过滤顺序与对Request的过滤顺序正好相反,具体如下图所示。
我们进行简单的模拟,创建Request和Reponse类,分别用于封装请求和响应消息。创建一个Filter接口,创建两个实现该Filter接口的过滤器HTMLFilter和SensitiveFilter,分别用于对消息进行简单的过滤处理。创建一个过滤器链FilterChain,在FilterChain中按序加入过滤器,FilterChain也实现Filter接口,这样便于两条过滤器链的连接。具体代码如下。
package com.zj.chain;
public class Request {
private String requestStr;
public String getRequestStr() {
return requestStr;
}
public void setRequestStr(String requestStr) {
this.requestStr = requestStr;
}
}
package com.zj.chain;
public class Response {
private String responseStr;
public String getResponseStr() {
return responseStr;
}
public void setResponseStr(String responseStr) {
this.responseStr = responseStr;
}
}
package com.zj.chain;
public interface Filter {
void doFilter(Request request,Response response,FilterChain fc);
}
package com.zj.chain;
public class HTMLFilter implements Filter {
@Override
public void doFilter(Request request, Response response,FilterChain fc) {
request.setRequestStr(request.getRequestStr().replaceAll("<", "[").replaceAll(">", "]")+"--HTML");
fc.doFilter(request, response, fc);
response.setResponseStr(response.getResponseStr().replaceAll("<", "[").replaceAll(">", "]")+"--HTML");
}
}
package com.zj.chain;
public class SensitiveFilter implements Filter{
@Override
public void doFilter(Request request, Response response,FilterChain fc) {
request.setRequestStr(request.getRequestStr().replaceAll("敏感", "").replace("被就业", "就业")+"--Sensitive");
fc.doFilter(request, response, fc);
response.setResponseStr(response.getResponseStr().replaceAll("敏感", "").replace("被就业", "就业")+"--Sensitive");
}
}
package com.zj.chain;
import java.util.ArrayList;
import java.util.List;
public class FilterChain implements Filter{
List<Filter> filters=new ArrayList<Filter>();
int index=0;
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);
}
}
package com.zj.chain;
public class Main {
public static void main(String[] args){
String msg1="大家好,这是request的字符串,<script>,敏感,被就业,认真学习设计模式";
String msg2="大家好,这是response的字符串,<script>,敏感,被就业,认真学习设计模式";
FilterChain fc=new FilterChain();
fc.addFilter(new HTMLFilter())
.addFilter(new SensitiveFilter());
Request request=new Request();
request.setRequestStr(msg1);
Response response=new Response();
response.setResponseStr(msg2);
fc.doFilter(request, response,fc);
System.out.println(request.getRequestStr());
System.out.println(response.getResponseStr());
}
}
运行结果如下:
从运行结果可以看出,对Response消息的过滤处理的顺序和对Request消息过滤处理的顺序正好相反。类的具体调用关系如下:
本设计模式的巧妙之处在于doFilter(Request,Response,FilterChain)方法不仅带有请求和响应的参数,还带有过滤器链本身。FilterChain调用一个过滤器对request消息进行过滤处理后,使用过滤器链本身去调用下一个过滤器,直到所有的过滤器都调用完,再依次返回,逆序调用过滤器,从而实现了对Response消息的逆序过滤。