首页 > 代码库 > 设计模式

设计模式

1.过滤器模式

  • 不带回调的过滤器
技术分享

 request发送请求,在我的测试程序中经历了三个过滤器,每个过滤器过滤或者处理request请求的内容。
 
HtmlFilter.java : 过滤 "<" 和 ">" 变为 "[" 和 "]"

  

/**
* HtmlFilter 过滤 "<" 和 ">" 变为 "[" 和 "]"
* @author hp
*
*/
publicclassHtmlFilterimplementsFilter{
@Override
publicvoid doFilter(Request request){
String str = request.getRequestString().replace("<","[").replace(">","]");
request.setRequestString(str);
}
}

 

 
SymbolFilter.java : 将"^^" 变为 "^|^"
/**
* SymbolFilter 将"^^" 变为 "^|^"
* @author hp
*
*/
publicclassSymbolFilterimplementsFilter{
@Override
publicvoid doFilter(Request request){
String str = request.getRequestString().replace("^^","^|^");
request.setRequestString(str);
}
}

 

 
WorldFilter.java : 过滤 "我日" 变为 "**"
/**
* WorldFilter 过滤 "我日" 变为 "**"
* @author hp
*
*/
publicclassWorldFilterimplementsFilter{
@Override
publicvoid doFilter(Request request){
String str = request.getRequestString().replace("我日","**");
request.setRequestString(str);
}
}

 

 
Filter.java : 过滤器接口,让所有的过滤器实现该接口,统一过滤的方法
/**
* 过滤器接口,让所有的过滤器实现该接口,统一过滤的方法
* @author hp
*
*/
publicinterfaceFilter{
publicvoid doFilter(Request request);
}

 

FilterChain.java : 过滤器链,里面存放了各种过滤器。
/**
* 过滤器链,里面存放了各种过滤器。
*
* 注意:如果该过滤器链没有实现 Filter 则存放的只能是过滤器。
* 如果该过滤器链实现了 Filter 接口,则可以将一个过滤器链看作一个整体添加进去
* @author hp
*
*/
publicclassFilterChainimplementsFilter{
//过滤器容器,用来存放过滤器
privateList<Filter> filters;
//构造方法,此时用来初始化容器
publicFilterChain(){
filters =newArrayList<Filter>();
}
//过滤方法,通过遍历调用每一个过滤器的方法
publicvoid doFilter(Request request){
for(Filter filter : filters){
filter.doFilter(request);
}
}
//添加过滤器的方法,返回是 FilterChain 本身,方便链式调用
publicFilterChain addFilter(Filter filter){
filters.add(filter);
returnthis;
}
}

 

 
Request.java : 代表一个消息,在JavaWeb中有很多内容,这里仅仅假设只有一个字符串
/**
* Request 类,代表一个消息,在JavaWeb中有很多内容,这里仅仅假设只有一个字符串
* @author hp
*
*/
publicclassRequest{
privateString requestString;
publicString getRequestString(){
return requestString;
}
publicvoid setRequestString(String requestString){
this.requestString = requestString;
}
}

 

 
Test.java : 测试过滤器
/**
* 测试过滤器
*
* @author hp
*
*/
publicclassTest{
publicstaticvoid main(String[] args){
// 给Request初始化数据
String str ="我日,<script>,^^ 我很好";
Request request =newRequest();
request.setRequestString(str);
//给 FilterChain 初始化,添加过滤器
FilterChain chain =newFilterChain();
chain.addFilter(newHtmlFilter())
.addFilter(newSymbolFilter())
.addFilter(newWorldFilter());
//调用过滤链的过滤的方法,实现过滤
chain.doFilter(request);
System.out.println(request.getRequestString());
}
}

 

 
测试结果如下:
 
技术分享
 

 

  • 带回调的过滤器:
 
技术分享
带回调的的过滤器是 struts2 中过滤器的核心思想,里面主要采用的是递归调用。每一个 Filter(HtmlFilter,SymbolFilter,WorldFilter) 的 doFilter(Request request,Response response, FilterChain chain) 方法里面都有 FilterChain ,可以得到所有的过滤器每一个 Filter 通过 FilterChain 调用下一个 Filter, 最后 FilterChain  中递归结束之后开始执行处理 response 的代码。
 
 
HtmlFilter.java 
/**
* @author hp
*
*/
publicclassHtmlFilterimplementsFilter{
@Override
publicvoid doFilter(Request request,Response response,FilterChain chain){
//此处可以调用处理 request 的代码
System.out.println("HtmlFilter----request");
//通过 FilterChain 来调用下一个 Filter
chain.doFilter(request, response, chain);//建议此处打断点,使用 debug 来查看调用过程
//此处可以调用处理 response 的代码
System.out.println("HtmlFilter----response");//建议此处打断点,使用 debug 来查看调用过程。
}
}

 

 
 
SymbolFilter.java
/**
* @author hp
*
*/
publicclassSymbolFilterimplementsFilter{
@Override
publicvoid doFilter(Request request,Response response,FilterChain chain){
//此处可以调用处理 request 的代码
System.out.println("SymbolFilter----request");//建议此处打断点,使用 debug 来查看调用过程
//通过 FilterChain 来调用下一个 Filter
chain.doFilter(request, response, chain);
//此处可以调用处理 response 的代码
System.out.println("SymbolFilter----response");//建议此处打断点,使用 debug 来查看调用过程
}
}

 

 
WorldFilter.java
/**
* @author hp
*
*/
publicclassWorldFilterimplementsFilter{
@Override
publicvoid doFilter(Request request,Response response,FilterChain chain){
//此处可以调用处理 request 的代码
System.out.println("WorldFilter----request");//建议此处打断点,使用 debug 来查看调用过程
//通过 FilterChain 来调用下一个 Filter
chain.doFilter(request, response, chain);
//此处可以调用处理 response 的代码
System.out.println("WorldFilter----response");//建议此处打断点,使用 debug 来查看调用过程
}
}

 

 
Filter.java 
/**
* 过滤器接口,让所有的过滤器实现该接口,统一过滤的方法
* @author hp
*
*/
publicinterfaceFilter{
publicvoid doFilter(Request request,Response response,FilterChain chain);
}

 

 
FilterChain.java
/**
* 过滤器链,里面存放了各种过滤器。
*
* 注意:如果该过滤器链没有实现 Filter 则存放的只能是过滤器。
* 如果该过滤器链实现了 Filter 接口,则可以将一个过滤器链看作一个整体添加进去
* @author hp
*
*/
publicclassFilterChainimplementsFilter{
//过滤器容器,用来存放过滤器
privateList<Filter> filters;
//过滤器的下标,
privateint indexFilter =0;
//构造方法,此时用来初始化容器
publicFilterChain(){
filters =newArrayList<Filter>();
}
//过滤方法,通过下标遍历每一个 Filter
publicvoid doFilter(Request request,Response response,FilterChain chain){
//递归的边界判断,当所有的过滤器执行完毕,跳出递归
if(indexFilter == filters.size()){
return;
}
Filter filter = filters.get(indexFilter);//建议此处打断点,使用 debug 可以查看当前的Filter是什么
indexFilter ++;
//调用下一个过滤器
filter.doFilter(request, response, chain);
}
//添加过滤器的方法,返回是 FilterChain 本身,方便链式调用
publicFilterChain addFilter(Filter filter){
filters.add(filter);
returnthis;
}
}

 

 
 
Request.java
/**
* Request 类,在JavaWeb中有很多内容。此处什么都不写,仅仅为了了解调用的步骤
* @author hp
*
*/
publicclassRequest{
}

 

 
Test.java
/**
* 测试过滤器
*
* @author hp
*
*/
publicclassTest{
publicstaticvoid main(String[] args){
Request request =newRequest();
Response response =newResponse();
//给 FilterChain 初始化,添加过滤器
FilterChain chain =newFilterChain();
chain.addFilter(newHtmlFilter())
.addFilter(newSymbolFilter())
.addFilter(newWorldFilter());
//调用过滤链的过滤的方法,实现过滤
chain.doFilter(request, response, chain);
}
}

 

 
测试结果:
建议使用debug详细了解调用的过程,打断点的地方在代码中有注释。
 
技术分享
 

 
 
 

 

设计模式