文档章节

将几个Filter整合成一个Filter

abcijkxyz
 abcijkxyz
发布于 2016/07/08 16:28
字数 533
阅读 4
收藏 0

 CAS-Client的客户端配置还是多Filter,这个对于接入系统比较繁琐,我试着将这几个Filter合并成一个。

 

FilterChainProxy :其职责是给web.xml使用,接受其他需要合并的Filter的参数,初始化其他Filter.

FilterInvocation:doFilter的参数的封装,取得路径信息等。

VirtualFilterChain:实现FilterChain,

代码如下:

FilterChainProxy

public class FilterChainProxy extends AbstractConfigurationFilter {

	Logger logger = Logger.getLogger(FilterChainProxy.class);

	private Filter[] filters;

	/* (non-Javadoc)
	 * @see javax.servlet.Filter#destroy()
	 */
	public void destroy() {

		for (int i = 0; i < filters.length; i++) {
			if (filters[i] != null) {
				if (logger.isDebugEnabled()) {
					logger.debug("Destroying Filter defined in ApplicationContext: '" + filters[i].toString() + "'");
				}

				filters[i].destroy();
			}
		}

	}

	/* (non-Javadoc)
	 * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
			ServletException {
		 FilterInvocation fi = new FilterInvocation(request, response, chain);
		
		if (filters.length == 0) {
			if (logger.isDebugEnabled()) {
				logger.debug(fi.getRequestUrl()+" has an empty filter list");
			}
			chain.doFilter(request, response);

			return;
		}
		
		VirtualFilterChain virtualFilterChain = new VirtualFilterChain(fi, filters);
		virtualFilterChain.doFilter(fi.getRequest(), fi.getResponse());

	}

	/* (non-Javadoc)
	 * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
	 */
	public void init(FilterConfig filterConfig) throws ServletException {
		filters = obtainAllDefinedFilters();

		for (int i = 0; i < filters.length; i++) {
			if (filters[i] != null) {
				if (logger.isDebugEnabled()) {
					logger.debug("Initializing Filter defined in ApplicationContext: '" + filters[i].toString() + "'");
				}
				filters[i].init(filterConfig);
			}
		}

	}
	/**
	 * 初始化单点登录需要的过滤器
	 * @return
	 */
	private Filter[] obtainAllDefinedFilters() {

		Set<Filter> list = new LinkedHashSet<Filter>();
		// SingleSignOutFilter
		list.add(new SingleSignOutFilter());
		// AuthenticationFilter
		list.add(new AuthenticationFilter());
		// Cas20ProxyReceivingTicketValidationFilter
		list.add(new Cas20ProxyReceivingTicketValidationFilter());
		// AssertionThreadLocalFilter
		list.add(new AssertionThreadLocalFilter());
		// HttpServletRequestWrapperFilter
		list.add(new HttpServletRequestWrapperFilter());

		return (Filter[]) list.toArray(new Filter[0]);
	}

VirtualFilterChain

private class VirtualFilterChain implements FilterChain {
		private FilterInvocation fi;
		private Filter[] additionalFilters;
		private int currentPosition = 0;

		public VirtualFilterChain(FilterInvocation filterInvocation, Filter[] additionalFilters) {
			  this.fi = filterInvocation;
	          this.additionalFilters = additionalFilters;
		}

		public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
			if (currentPosition == additionalFilters.length) {
				if (logger.isDebugEnabled()) {
					logger.debug(fi.getRequestUrl()
							+ " reached end of additional filter chain; proceeding with original chain");
				}

				fi.getChain().doFilter(request, response);
			} else {
				currentPosition++;

				if (logger.isDebugEnabled()) {
					logger.debug(fi.getRequestUrl() + " at position " + currentPosition + " of "
							+ additionalFilters.length + " in additional filter chain; firing Filter: '"
							+ additionalFilters[currentPosition - 1] + "'");
				}

				additionalFilters[currentPosition - 1].doFilter(request, response, this);
			}
		}

	}


FilterInvocation

public class FilterInvocation {
	private FilterChain chain;
	private ServletRequest request;
	private ServletResponse response;

	public FilterInvocation(ServletRequest request, ServletResponse response, FilterChain chain) {
		if ((request == null) || (response == null) || (chain == null)) {
			throw new IllegalArgumentException("Cannot pass null values to constructor");
		}

		if (!(request instanceof HttpServletRequest)) {
			throw new IllegalArgumentException("Can only process HttpServletRequest");
		}

		if (!(response instanceof HttpServletResponse)) {
			throw new IllegalArgumentException("Can only process HttpServletResponse");
		}

		this.request = request;
		this.response = response;
		this.chain = chain;
	}

	public FilterChain getChain() {
		return chain;
	}

	/**
	 * Indicates the URL that the user agent used for this request.<P>The returned URL does <b>not</b> reflect
	 * the port number determined from a {@link org.acegisecurity.util.PortResolver}.</p>
	 *
	 * @return the full URL of this request
	 */
	public String getFullRequestUrl() {
		return UrlUtils.getFullRequestUrl(this);
	}

	public HttpServletRequest getHttpRequest() {
		return (HttpServletRequest) request;
	}

	public HttpServletResponse getHttpResponse() {
		return (HttpServletResponse) response;
	}

	public ServletRequest getRequest() {
		return request;
	}

	/**
	 * Obtains the web application-specific fragment of the URL.
	 *
	 * @return the URL, excluding any server name, context path or servlet path
	 */
	public String getRequestUrl() {
		return UrlUtils.getRequestUrl(this);
	}

	public ServletResponse getResponse() {
		return response;
	}

	public String toString() {
		return "FilterInvocation: URL: " + getRequestUrl();
	}
}



 

本文转载自:http://blog.csdn.net/yuwenruli/article/details/6829646

共有 人打赏支持
abcijkxyz
粉丝 63
博文 6196
码字总数 1876
作品 0
深圳
项目经理
私信 提问
对chain.doFilter(request,response)的理解

他的作用是将请求转发给过滤器链上下一个对象。这里的“下”指的是哪里 ? 指的是下一个filter,如果没有filter那就是你请求的资源。 一般filter都是一个链,web.xml 里面配置了几个就有几个。...

simplesns
2010/12/08
27.4K
5
springboot的shiro配置之过滤器

springboot整合shiro的文章到处都是。包括springboot的官网都有相应的例子。但是这块有个注意点,需要那些从springmvc迁到springboot的朋友注意下。这个问题困扰我了两三天,今天分享出来让后...

hyssop
2016/11/21
97
0
设计模式——责任链模式

使用场景: 现在有如下字符 :) English < > ,现在想把其转换为 ^V^ 英文 [],并且根据要求对 :) English < > 这三类字符分别转换 解决办法: (1)if else进行处理,低级的办法,不多说。 ...

wjk_snail
2015/09/15
61
0
应用Bloom Filter的几个小技巧

下面列举几个基于标准Bloom Filter的小技巧: 1. 求两个集合的并。假设有两个Bloom Filter分别表示集合S1和S2,它们位数组的大小相同且使用同一组哈希函数,那么要求表示S1和S2并集的Bloom F...

Picasso
2011/09/24
0
0
使用BloomFilter优化scrapy-redis去重

使用BloomFilter优化scrapy-redis去重 1. 背景 做爬虫的都知道,scrapy是一个非常好用的爬虫框架,但是scrapy吃内存非常的厉害。其中有个很关键的点就在于去重。 “去重”需要考虑三个问题:...

zwq912318834
2017/12/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

C#默认OrderBy()函数的排序问题

昨天在客户现场遇到一个很奇葩的问题,猜下下面代码的排序输出是什么: static void Main(){ List<string> strs = new List<string>(){"11", "12", "1:"}; foreach(string str i......

Airship
26分钟前
2
0
Vue调试神器Vue.js devtools

前言: Vue.js devtools是一个高效的vue项目可视化检查工具,其主要功能就是可以快速查看页面结构、组件中的data变量、computed计算属性、props父组件传过来的值等等 Chrome上的使用方法: 科学...

JamesView
31分钟前
14
0
最全面的IGMP协议总结!

IGMP互联网组管理协议是TCP/IP 协议族中负责IP组播成员管理的协议,用来在IP主机和与其直接相邻的组播路由器之间建立、维护组播组成员关系。 一、IGMP 简介 IGMP(Internet Group Management...

linuxprobe16
35分钟前
1
0
node-sass 安装失败的各种坑

开始的时候引入别人的一个项目 npm install npm run dev 启动项目 报错 > sell@1.0.0 dev E:\web_hwf\Vue\02app > node build/dev-server.js Listening at http://localhost:8888 webpack: w......

黑魔法
37分钟前
1
0
Qemu中PCI设备透传(PCI-Assign)源码分析

在网上看到很多人说Qemu的PCI-Assign透传不支持IOMMU,而VFIO透传却可以(还被当做一种优势进行推荐)。而VFIO跟SRIOV并非有必然联系,那就是说VFIO和PCI-Assign进本都是靠软件实现的了?既然...

LastRitter
39分钟前
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部