首页 > 代码库 > 模拟JavaEE的Filter
模拟JavaEE的Filter
做JavaEE开发几年了,只是知道Filter、Servlet的执行流程,但是一直对Filter是如何实现的并不了解。
Filter的处理中的FilterChain是J2ee的接口,并没有提供实现,具体的实现有各个Servlet容器来实现的。今天就找了个时间,简单的看了一下Tomcat的FilterChain的内部实现,做了一个大致的了解,下面就来模拟了一下。
以我对Tomcat中Filter简单实现,设计了下面的类图:
Filter接口、FilterChain,是完全按照J2EE中的Filter接口、FilterChain来设计的。
FilterContext是Filter的执行上下文。
DefaultFilterChain用于调配各个过滤器的执行。
Request是封装的简易请求。
FirstFilter、SecondFilter用于模拟我们开发时自定义的Filter。
Client用于测试。
下面附上代码:
// J2EE的Filter/** * Created with IntelliJ IDEA. * User: Administrator * Date: 14-7-28 * To change this template use File | Settings | File Templates. */public interface Filter { public void init(FilterConfig cfg); public void doFilter(Request request, Object response, FilterChain chain); public void destroy();} // J2EE的FilterChianpublic interface FilterChain { void doFilter(Request request, Object response);} // Filter配置信息,用于Filter初始化public class FilterConfig { private String name; public FilterConfig(){} public FilterConfig(String name){ this.name=name; } public String getName() { return name; } public void setName(String name) { this.name = name; }} // 模拟Filter执行的上下文public class FilterContext { List<Filter> filters=new ArrayList<Filter>(); public FilterContext(){ } public void addFilter(Filter filter, FilterConfig cfg){ this.filters.add(filter); filter.init(cfg); } public void remvoeFilter(Filter filter){ this.filters.remove(filter); filter.destroy(); } public Filter getFilter(int index){ return filters.get(index); }} // 自定义请求public class Request { private String url; private String param; public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getParam() { return param; } public void setParam(String param) { this.param = param; } @Override public String toString() { return this.url+"?"+this.getParam(); }} // 模拟FilterChain的内部实现public class DefaultFilterChain implements FilterChain { private FilterContext context; private int i=0; public void doFilter(Request request, Object response) { if(i<context.filters.size()){ context.getFilter(i++).doFilter(request, response, this); } else { System.out.println("过滤器已处理完毕,现在由Servlet来处理请求。。。"); } } public void setContext(FilterContext context) { this.context = context; }}
上面的几个类模拟了J2EE对于FIlter的设计。
接下来,自定义两个Filter:
public class FirstFilter implements Filter { private String name; public void init(FilterConfig cfg) { this.name=cfg.getName(); System.out.println("初始化 "+cfg.getName()); } public void doFilter(Request request, Object response, FilterChain chain) { System.out.println(this.name+": "+request); if (request.getUrl()!=null){ chain.doFilter(request,response); } } public void destroy() { //To change body of implemented methods use File | Settings | File Templates. }} public class SecondFilter implements Filter { private String name; public void init(FilterConfig cfg) { this.name=cfg.getName(); System.out.println("初始化 "+cfg.getName()); } public void doFilter(Request request, Object response, FilterChain chain) { System.out.println(this.name+": "+request); if (request.getUrl()!=null){ chain.doFilter(request,response); } } public void destroy() { //To change body of implemented methods use File | Settings | File Templates. }}
模拟客户端发送请求:
public class Client { public static void main(String[] args) throws InterruptedException { final FilterContext context=init(); final int poolsize=10;// 模拟多个请求 ExecutorService pool=Executors.newFixedThreadPool(poolsize); List<Callable<Object>> tasks=new ArrayList<Callable<Object>>(poolsize); for (int i=0; i<poolsize;i++){ tasks.add(new Callable<Object>() { public Object call() throws Exception { //客户端请求 Request request=new Request(); request.setUrl("http://localhost:8080/filter/hello..."); request.setParam("name=zhangsan&age=23&address=xxxxx"); Object response=new Object(); // 这里是模拟过滤器对请求过滤 DefaultFilterChain chain=new DefaultFilterChain(); chain.setContext(context); chain.doFilter(request,response); return response; } }); } pool.invokeAll(tasks); } // 初始化FilterContext static FilterContext init(){ // 初始化FilterContext并添加自定义Filter ,这个过程是模拟Web Server启动 FilterContext context=new FilterContext(); Filter filter=new FirstFilter(); context.addFilter(filter, new FilterConfig("firstFilter")); filter=new SecondFilter(); context.addFilter(filter, new FilterConfig("secondFilter")); return context; }}
这个模拟过程,只是模拟了发送请求,过滤器对请求过滤的过程。并没有对响应信息处理。
上面的模拟的执行结果:
初始化 firstFilter初始化 secondFilterfirstFilter: http://localhost:8080/filter/hello...?name=zhangsan&age=23&address=xxxxxsecondFilter: http://localhost:8080/filter/hello...?name=zhangsan&age=23&address=xxxxx过滤器已处理完毕,现在由Servlet来处理请求。。。firstFilter: http://localhost:8080/filter/hello...?name=zhangsan&age=23&address=xxxxxsecondFilter: http://localhost:8080/filter/hello...?name=zhangsan&age=23&address=xxxxx过滤器已处理完毕,现在由Servlet来处理请求。。。firstFilter: http://localhost:8080/filter/hello...?name=zhangsan&age=23&address=xxxxxsecondFilter: http://localhost:8080/filter/hello...?name=zhangsan&age=23&address=xxxxx过滤器已处理完毕,现在由Servlet来处理请求。。。firstFilter: http://localhost:8080/filter/hello...?name=zhangsan&age=23&address=xxxxxfirstFilter: http://localhost:8080/filter/hello...?name=zhangsan&age=23&address=xxxxxsecondFilter: http://localhost:8080/filter/hello...?name=zhangsan&age=23&address=xxxxxsecondFilter: http://localhost:8080/filter/hello...?name=zhangsan&age=23&address=xxxxx过滤器已处理完毕,现在由Servlet来处理请求。。。过滤器已处理完毕,现在由Servlet来处理请求。。。firstFilter: http://localhost:8080/filter/hello...?name=zhangsan&age=23&address=xxxxxsecondFilter: http://localhost:8080/filter/hello...?name=zhangsan&age=23&address=xxxxx过滤器已处理完毕,现在由Servlet来处理请求。。。firstFilter: http://localhost:8080/filter/hello...?name=zhangsan&age=23&address=xxxxxsecondFilter: http://localhost:8080/filter/hello...?name=zhangsan&age=23&address=xxxxx过滤器已处理完毕,现在由Servlet来处理请求。。。firstFilter: http://localhost:8080/filter/hello...?name=zhangsan&age=23&address=xxxxxfirstFilter: http://localhost:8080/filter/hello...?name=zhangsan&age=23&address=xxxxxfirstFilter: http://localhost:8080/filter/hello...?name=zhangsan&age=23&address=xxxxxsecondFilter: http://localhost:8080/filter/hello...?name=zhangsan&age=23&address=xxxxxsecondFilter: http://localhost:8080/filter/hello...?name=zhangsan&age=23&address=xxxxxsecondFilter: http://localhost:8080/filter/hello...?name=zhangsan&age=23&address=xxxxx过滤器已处理完毕,现在由Servlet来处理请求。。。过滤器已处理完毕,现在由Servlet来处理请求。。。过滤器已处理完毕,现在由Servlet来处理请求。。。
上面的是对Filter的模拟,具体是怎样一个过程,还需要认真的研究源码才可知晓。尽管如此,通过这个模拟至少对Filter的处理有一个简单的了解。
Filter的设计其实是按照AOP的思想设计的。为什么这么说,下一篇博客将揭晓。
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。