JavaEE过滤器处理原理

本文通过一个简单的示例展示了JavaEE中Filter的责任链模式实现原理。具体包括自定义Request和Response类,定义Filter接口及其实现,以及FilterChain类的使用。最后通过一个客户端程序演示了请求和响应如何被多个过滤器按顺序处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

     大家都知道JavaEE中的Filter是用了责任链模式来实现的,请求值先到达Filter,根据Filter在web.xml的配置顺序一个个按顺序地处理,处理完以后,再按反顺序来处理响应信息,有点像是一个栈(先处理请求的Filter,后处理响应)。下面就山寨一下它的实现,来说明它的实现原理。

package myself.filter;

/**
 * 请求
 * @author zyb
 * @since 2012-12-1
 *
 */
public class Request {

	private String value;

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}

}
 package myself.filter;

/**
 * 响应
 * 
 * @author zyb
 * @since 2012-12-1
 * 
 */
public class Response {

	private String value;

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}

}

 package myself.filter; 


/**
 * 过滤器接口
 * @author zyb
 * @since 2012-12-1
 *
 */
public interface Filter {

	/**
	 * 处理请求和响应
	 * @param request		请求
	 * @param response		响应
	 * @param chain			过滤器链
	 */
	void doFilter(Request request, Response response, FilterChain chain);
	
}

 package myself.filter; 


import java.util.ArrayList;
import java.util.List;

/**
 * 过滤器链
 * @author zyb
 * @since 2012-12-1
 *
 */
public class FilterChain implements Filter { // 在JavaEE的FilterChain源码中并没有实现Filter接口
	
	// 用于保存所有要处理的过滤器
	private List<Filter> filters = new ArrayList<Filter>();
	
	// 索引,用于记数
	private int index = 0;
	
	@Override
	public void doFilter(Request request, Response response, FilterChain chain) {
		// 如果所有的过滤器都已经处理完
		if (index == filters.size()) {
			return;
		}
		// 取出相应的过滤器
		Filter filter = filters.get(index);
		// 索引加1
		index++;
		// 调用具体的过滤器处理请求和响应
		filter.doFilter(request, response, chain);
	}

	// 往过滤器链中添加过滤器
	public void addFilter(Filter filter) {
		this.filters.add(filter);
	}
}

 package myself.filter;


/**
 * 客户端程序
 * @author zyb
 * @since 2012-12-1
 *
 */
public class Client {

	public static void main(String[] args) {
		Request request = new Request();
		request.setValue("abcd");
		Response response = new Response();
		FilterChain filter = new FilterChain();
		
		// 将请求值变成大写字母
		filter.addFilter(new Filter() {
			
			@Override
			public void doFilter(Request request, Response response, FilterChain chain) {
				System.out.println("第一个Filter处理...请求值:" + request.getValue());
				StringBuilder sb = new StringBuilder();
				for (int i = 0; i < request.getValue().length(); i++) {
					sb.append((char) (request.getValue().charAt(i) - 32));
				}
				Response result = new Response();
				result.setValue(sb.toString());
				chain.doFilter(request, response, chain);
				System.out.println("第一个Filter响应...响应值:" + result.getValue());
				
			}
		});
		
		// 将请求值加1
		filter.addFilter(new Filter() {
			
			@Override
			public void doFilter(Request request, Response response, FilterChain chain) {
				System.out.println("第二个Filter处理...请求值:" + request.getValue());
				StringBuilder sb = new StringBuilder();
				for (int i = 0; i < request.getValue().length(); i++) {
					sb.append((char) (request.getValue().charAt(i) + 1));
				}
				Response result = new Response();
				result.setValue(sb.toString());
				chain.doFilter(request, response, chain);
				System.out.println("第二个Filter响应...响应值:" + result.getValue());
			}
		});
		
		filter.doFilter(request, response, filter);
	}
}

打印信息:

第一个Filter处理...请求值:abcd

第二个Filter处理...请求值:abcd
第二个Filter响应...响应值:bcde
第一个Filter响应...响应值:ABCD

打印的信息跟前面说的是一致的,先进后出。。呵
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值