Filter介绍

Filter 可认为是 Servlet 的一种“加强版”,它主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理,是个典型的 处理链;

Filter 也可对用户请求生成响应,这一点与 Servlet 相同,但实际上很少会使用 Filter 向用户请求生成响应。

使用Filter完整的流程是:Filter对用户请求进行预处理,接着将请求交给 Servlet 进行处理并生成响应,最后 Filter 再对服务器响应进行后处理。

Filter 的几个用处:

1、在HttpServletRequest 到达 Servlet 之前,拦截客户的HttpServletRequest;

2、根据需要检查 HttpServletRequest, 也可以修改 HttpServletRequest 头和数据;

3、在 HttpServletResponse 到达客户端之前,拦截 HttpServletResponse;

4、根据需要检查 HttpServletResponse,也可以修改HttpServletResponse 头和数据;


Filter 的几个种类:

1、用户授权的 Filter:Filter 负责检查用户请求,根据请求过滤用户非法请求;

2、日志 Filter:详细记录某些特殊的用户请求;

3、负责解码的 Filter:包括对非标准编码的请求解码;

4、能改变 XML 内容的 XSLT Filter等。

5、Filter 可负责拦截多个请求或响应;一个请求或响应 也可以 被多个 Filter 拦截;


创建一个 Filter 的过程:

1、创建 Filter 处理类;

2、web.xml 文件中配置 Filter;


创建Filter类必须实现 javax.servlet.Filter 接口,在该接口中定义了如下三个方法:

void init(FilterConfig config):用于完成Filter的初始化。

void destroy():用于Filter销毁前,完成某些资源的回收。

void doFilter(ServletRequest  request, ServletResponse response, FilterChain chain):

实现过滤功能,该方法就是对,每个请求及响应增加的额外处理;

给出一个日志Filter例子,负责拦截所有的用户请求,并将请求信息记录在日志中:

<span style="white-space:pre">		</span>public class LogFilter implements Filter{
			private FilterConfig config;
			public void init(FilterConfig  config){	this.config = config;	}
			public void destroy(){	 this.config = null; 	}
			public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,ServletException<span style="white-space:pre">			</span>{
				//======下面代码对用户请求进行预处理========
				ServletContext context = this.config.getServletContext();
				long before = System.currentTimeMillis();
				System.out.println(” 开始过滤 ……“);
				HttpServletRequest hrequest = (HttpServletRequest) request;	//将请求转换成 HttpServletRequest请求
				System.out.println(”Filter 已经截获到用户的请求地址: “ + hrequest.getServletPath());//链式处理,请求依然到目的地址
				chain.doFilter(request,response);
				//========下面代码对服务器进行后处理=====
				long after = System.currentTimeMillis();
				System.out.println(” 过滤结束 ……“);
				System.out.println(“请求被定位到: ” + hrequest.getRequestURI() + “所花时间为: ”  + (after - before));
			}
		}

在上面请求的Filter中,仅在日志中记录请求的URL,对所有的请求都执行 chaindoFilter(request, response)方法,当 FIlter 对请求过滤后,依然将请求发送到目的地址。如果需要检查权限,可以在Filter 中根据用户请求的 HttpSession ,判断用户权限是否足够。如果权限不够,直接调用重定向即可,无须调用chain.doFilter()方法

配置Filter 跟 Servlet也是差不多:

配置Filter 的名字、配置 Filter 的拦截 URL 模式

区别在于,Servlet 通常只配置一个URL , Filter 可以同时拦截多个请求 的 URL。因此,在配置 Filter 的 URL模式时通常 使用 模式字符串,是的Filter 可以拦截多个请 求。

Filter 也支持两种配置方式  : Annotation配置、  web.xml 配置

主要讲讲 web.xml 配置:

<span style="white-space:pre">		</span><filter>
			<filter-name> log </filter-name>
			<filter-class> lee.LogFilter </filter-class>
		</filter>
		<filter-mapping>
			<filter-name> log </filter-name>
			<url-parttern> /* </url-parttern>
		</filter-mapping>

<url-parttern>/* 表示 会拦截所有用户请求。

实际上,Filter 跟 Servlet 极其相似,区别只是 Filter 的 doFilter()方法里多了一个 FIlterChain 的参数,通过该参数可以控制是否放行用户请求。

在实际项目中, FIlter 里 doFilter()方法里的代码就是从多个 Servlet 的 service()方法里抽取的通用代码,通过使用Filter 可以实现更好的代码复用。

假设系统包含多个 Servlet,这些Servlet都需要进行一些通用处理:比如 权限控制、记录日志等,这将导致在这些Servlet 的service()方法中有部分代码是相同的---为了解决这种代码重复的问题,我们可以考虑把这些通用的处理提取到 Filter 中完成,这样个 Servlet 中剩下的只是特定请求相关的处理代码,通用处理就交给 Filter 完成

其实这里给 AOP 做了铺垫,逻辑代码  业务代码 分离!

例如在 web.xml 中配置 Filter,关于 字符编码的问题

</pre><pre name="code" class="html">		<filter>
			<filter-name> autority </filter-name>
			<filter-class> lee.xxxxx </filter-class>
			<init-param>
				<param-name> encoding <param-name>
				<param-value> GBK <param-value>
			</init-param>
			<init-param>
				<param-name> loginPage <param-name>
				<param-value> /login.jsp <param-value>
			</init-param>
			<init-param>
				<param-name> proLogin <param-name>
				<param-value> /proLogin <param-value>
			</init-param>
		<filter>
		<filter-mapping>
			<filter-name> autoroty </filter-name>
			<url-pattern> /* </url-pattern>		//负责拦截的URL
		</filter-mapping>
上面代码 给 Filter 配置了三个配置参数, 指定 loginPage 为 /login.jsp , proLogin 为 /proLogin.jsp, 这表明,如果没有登录该应用,普通用户只能访问 /login.jsp 和 /proLogin.jsp 页面。只有当用户登录该应用后才可自由访问 其他页面。
 
 









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值