常用的网络通讯框架主要有:Mina ,Grizzly,Cindy,Netty 等,看了下cindy的代码,和mina有很多相似的地方,实现的比mina精简很多,据说性能还要好于mina.参照代码实现了一下filterchain的HelloWorld版,简单说明一下cindy里对filterchain模式的应用.
首先定义filter接口,filter接口封装了session中的sessionStarted,sessionClosed,messageReceived等方法,为了简单,我只模拟一个send方法,用一个String的消息代替session对象
public interface Filter {
void send(FilterChain chain, String msg);
}
FilterChain是filter的一个管理容器,在cindy里filterChain管理2种filter,第一种是系统内部的filter,另外一种是用户定义的filter,看一下FilterChain的定义
public interface FilterChain {
public void addFilter(Filter filter);
public void send(String msg);
}
为了简单,我只定义了addFilter,而没有定义removeFilter方法,send方法其实是filterChain调用所管理的所有filter的一个方法,看一个具体实现
public abstract class AbstractFilterChain implements FilterChain {
protected static final Filter NULL_FILTER = new NullFilter();
protected static final Filter DISPACHER_FILTER = new FirstInnerFilter();
protected abstract Filter nextFilter();
public Filter next() {
Filter filter = nextFilter();
return filter != null ? filter : NULL_FILTER;
}
@Override
public void send(String msg) {
next().send(this, msg);
}
}
在这个抽象类里,我们基本可以看出filterChain是如何管理所有filter的,首先filterChain里定义了2个系统内部的filter,FirstInnerFilter是filterChain里的第一个filter,在cindy里的名称是DispacherFilter,里面是通过一个线程池DefaultDispacher调用所有的filter的,NullFilter是系统的最后一个filter,当然我的实现是非常简单的,cindy实际上定义了很多个系统内部的filter,其中还有一个PacketDecoderFilter用于解码的filter,主要处理字节流转换成java对象,类似netty 里的MessageReconizer
每次调用send,方法,都会通过nextFilter取得下一个filter进行调用,看一下最终实现
public class DefaultFilterChain extends AbstractFilterChain {
private Filter[] appFilters = new Filter[0];
private Filter dispacherFilter = DISPACHER_FILTER;
private int cursor = -1;
@Override
public void addFilter(Filter filter) {
Filter[] newFilters = new Filter[appFilters.length + 1];
if (appFilters.length > 0) {
System.arraycopy(appFilters, 0, newFilters, 0, appFilters.length);
}
newFilters[appFilters.length] = filter;
appFilters = newFilters;
}
@Override
protected Filter nextFilter() {
Filter filter = null;
if (dispacherFilter != null) {
filter = dispacherFilter;
dispacherFilter = null;
} else if (++cursor < appFilters.length) {
filter = appFilters[cursor];
} else {
filter = NULL_FILTER;
}
return filter;
}
}
addFilter比较好理解用于向chain容器内添加用户定义的filter
nextFilter是整个chain的调度中心,流程是:
首先调用系统内部的FirstInnerFilter,然后开始循环调用所有用户自定义的filter,最后是
系统内部的NullFilter,我们再看看各种filter的实现
public class FirstInnerFilter implements Filter {
@Override
public void send(FilterChain chain, String msg) {
System.out.println("first inner filter(Dispacher Filter): " + msg);
chain.send(msg);
}
}
FirstInnerFilter是容器里首个被调用的filter,在调用方法里,通过chain.send(msg),其实就是调用 FilterChain的 next().send(msg)方法,依此类推,遍历容器内所有的filter,下面是其他的实现:
public class NullFilter implements Filter {
@Override
public void send(FilterChain chain, String msg) {
System.out.println("the final of the chain, NullFilter: " + msg);
}
}
public class FilterAdapter implements Filter {
@Override
public void send(FilterChain chain, String msg) {
chain.send(msg);
}
}
所有的用户定义的filter继承自FilterAdapter,其实也可以不必这样的,可以直接在应用filter里调用chain.send(msg);
以下是两个用户自定义的filter示例
public class AppFilterA extends FilterAdapter {
@Override
public void send(FilterChain chain, String msg) {
System.out.println("AppFilterA: " + msg);
super.send(chain, msg);
}
}
public class AppFilterB extends FilterAdapter {
@Override
public void send(FilterChain chain, String msg) {
System.out.println("AppFilterB: " + msg);
super.send(chain, msg);
}
}
最后看一下测试代码:
public class TestChain {
public void send(String msg) {
DefaultFilterChain chain = new DefaultFilterChain();
chain.addFilter(new AppFilterA());
chain.addFilter(new AppFilterB());
chain.send(msg);
}
public static void main(String[] args) {
new TestChain().send("test msg");
}
}
cindy里的DefaultFilterChain是定义在AbstractSession里的一个内部类.
程序输出:
first inner filter(Dispacher Filter): test msg
AppFilterA: test msg
AppFilterB: test msg
the final of the chain, NullFilter: test msg
以上是一个超简单的模拟cindy里filterChain的一个实现,源码结构大体是这样,当然功能要丰富得多,支持倒序和正序两种chain的执行顺序等.
源代码参照cindy3.0b1
分享到:
相关推荐
不使用Servlet Filter接口,自定义FilterChain处理多个Filter执行顺序问题
public void doFilter ServletRequest sRequest ServletResponse sResponse FilterChain chain throws IOException ServletException { HttpServletRequest request HttpServletRequest sRequest; String ...
简单的责任链代码 博文链接:https://liucunzhi.iteye.com/blog/1636463
* 当前类名:FilterChain.java * 项目名称:JavaStudy * 创建时间:2011-12-28 */ package org.java.com.design.filter; import java.util.ArrayList; import java.util.List; public class FilterChain ...
* 当前类名:FilterChain.java * 项目名称:JavaStudy * 创建时间:2011-12-28 */ package org.java.com.design.filter; import java.util.ArrayList; import java.util.List; public class FilterChain ...
import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax....
b、doFilter(ServletRequest,ServletResponse,FilterChain): 这个方法完成实际的过滤操作,当客户请求访问于过滤器关联的URL时,Servlet容器将先调用过滤器的doFilter方法。FilterChain参数用于访问后续过滤器。 ...
CXF 是以消息处理为中心的,熟悉 JSP/Servlet 的开发者可以将拦截器视为 CXF 架构中的“Filter”,拦截器链也与“FilterChain”类似。通过拦截器,开发者可以方便地在消息传递、 处理的整个过程中对 CXF 进行扩展。...
在 Servlet API 中定义了三个接口类来开供开发人员编写 Filter 程序:Filter, FilterChain, FilterConfig。 Filter 程序是一个实现了 Filter 接口的 Java 类,与 Servlet 程序相似,它由 Servlet 容器进行调用和...
MVC模式(model view controller) 模型:封装应用程序的数据和业务逻辑(POJO...对于servlet来说,拦截资源不是其所擅长的filter中的filterchain,这个API是servlet所没有的 Struts2中最主要的一个就是过滤器filter
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (encoding != null) { request.setCharacterEncoding(encoding); ...
2. FilterChain接口中仅定义一个方法:public void doFilter(ServletRequest req,ServletResponse res),该方法的作用是。() (1分) A.用于将请求/响应继续沿过滤器链向后传给下一个过滤器。如果调用该方法的过滤...
本文实例分析了jQuery解析json数据的方法。分享给大家供大家参考,具体如下: 先来看看我们的Json数据格式: [ {id:01,name:"小白",old:29,sex:"男"}, {id:02,name:"小蓝",old:29,sex:"男"}, {id:03,name:"小雅",...
FilterChain filters=new FilterChain(); DocumentFilter filter=new LinkLocalizer(); filters.add(filter); robby.setFilters(filters); 6.启用机器人运行期监控。 当启动spider程序后,程序利用回调接口...
JAVA配置跨越访问Filter APP要访问WEB系统,需要进行跨域设置 关键: public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {}
FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; HttpSession session ...
FilterChain FilterConfig GenericServlet HttpServlet HttpServletRequest HttpServletRequestWrapper HttpServletResponse HttpServletResponseWrapper HttpSession HttpSessionActivationListener ...
培训主要学习以下几个知识点: 1.Filter简介 2.Filter基本工作原理 3.Filter的主要作用及Filter API 4.Filter接口 5.FilterChain接口 6.FilterConfig接口 7.Filter的部署 8.Filter的典型应用
import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax....
javax.servlet.FilterChain javax.servlet.http.Cookie javax.servlet.FilterConfig javax.servlet.ServletConfig javax.servlet.GenericServlet javax.servlet.ServletContext javax.servlet.ServletRequest javax....