JavaWeb学习——Filter过滤器

一、Filter概述

  1. 什么是Filter:
    Filter又称为过滤器,是JavaWeb三大组件(Servlet、Listener、Filter)之一,它与Servlet很相似,但作用却不同,Filter用来拦截请求的,而不是处理请求的。
  2. Filter的作用:
    WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
  3. Filter的拦截过程:
    Filter接口中有一个doFilter方法,当我们编写好Filter,并配置对哪个web资源进行拦截后,WEB服务器每次在调用web资源的service方法之前,都会先调用一下filter的doFilter方法,因此,在该方法内编写代码可达到如下目的:
     > 调用目标资源之前,让一段代码执行。
     > 是否调用目标资源(即是否让用户访问web资源)。
     > 调用目标资源之后,让一段代码执行。
    web服务器在调用doFilter方法时,会传递一个filterChain对象进来,filterChain对象是filter接口中最重要的一个对象,它也提供了一个doFilter方法,开发人员可以根据需求决定是否调用此方法,调用该方法,则web服务器就会调用web资源的service方法,即web资源就会被访问,否则web资源不会被访问。

二、Filter之HelloWorld

编写一个Filter一般需要以下步骤:

  1. 写一个类实现Filter接口:
public class HelloFilter implements Filter {
	//Filter初始化后调用init()
	public void init(FilterConfig filterConfig) throws ServletException {}
	
	//用于处理过滤请求的方法
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		//过滤前执行的代码
		System.out.println("filter start...");
		//代表过滤后放行
		chain.doFilter(request, response);
		//过滤后执行的代码
		System.out.println("filter end...");
	}
	
	//Filter销毁前调用destroy()
	public void destroy() {}
}
  1. 在web.xml文件中配置Filter
<filter>
  	<filter-name>helloFilter</filter-name>
  	<filter-class>cn.practice.filter.HelloFilter</filter-class>
</filter>
<filter-mapping>
	<filter-name>helloFilter</filter-name>
	<url-pattern>/index.jsp</url-pattern>
</filter-mapping>

此时当访问index.jsp页面时,会执行HelloFilter的doFilter()方法。

三、Filter的生命周期

 Filter的生命周期跟Servlet很相似,同样包含以下三个生命周期方法:

  • init(FilterConfig filterConfig):
    在服务器启动时会创建Filter实例,并且每个类型的Filter只创建一个实例,从此不再创建!在创建完Filter实例后,会马上调用init()方法完成初始化工作,这个方法只会被执行一次;
  • doFilter(ServletRequest req,ServletResponse res,FilterChain chain):
    这个方法会在用户每次访问“目标资源(<url-pattern>index.jsp</url-pattern>)”时执行,如果需要“放行”,那么需要调用FilterChain的doFilter(ServletRequest,ServletResponse)方法,如果不调用FilterChain的doFilter()方法,那么目标资源将无法执行;
  • destroy():
    服务器会在创建Filter对象之后,把Filter放到缓存中一直使用,通常不会销毁它。一般会在服务器关闭时销毁Filter对象,在销毁Filter对象之前,服务器会调用Filter对象的destory()方法。

FilterConfig:
 Filter接口中的init()方法的参数类型为FilterConfig类型。它的功能与ServletConfig相似,与web.xml文件中的配置信息对应。下面是FilterConfig的功能介绍:

  • ServletContext getServletContext():获取ServletContext的方法;
  • String getFilterName():获取Filter的配置名称;与元素对应;
  • String getInitParameter(String name):获取Filter的初始化配置,与<init-param>元素对应;
  • Enumeration getInitParameterNames():获取所有初始化参数的名称。

FilterChain:
 doFilter()方法的参数中有一个类型为FilterChain的参数,该类内部只有一个方法:doFilter(ServletRequest,ServletResponse)。此方法代表放行,此处有两种情况:

  1. 若当前过滤的目标资源只有这一个Filter或此Filter是最后一个过滤器,那么调用doFilter()方法表示执行目标资源。
  2. 若当前过滤的目标资源存在多个Filter且此Filter不是最后一个过滤器,那么调用doFilter()方法代表执行下一个过滤器的doFilter()方法。

四、Filter的四种拦截方式

 过滤器有四种拦截方式,分别为:

  • REQUEST(默认拦截方式):
    直接访问目标资源时执行过滤器。包括:在地址栏中直接访问、表单提交、超链接、重定向,只要在地址栏中可以看到目标资源的路径,就是REQUEST;

  • FORWARD:
    转发访问执行过滤器。包括RequestDispatcher#forward()方法、<jsp:forward>标签都是转发访问;

  • INCLUDE:
    包含访问执行过滤器。包括RequestDispatcher#include()方法、<jsp:include>标签都是包含访问;

  • ERROR:
    当目标资源在web.xml中配置为中时,并且真的出现了异常,转发到目标资源时,会执行过滤器。

    可以在<filter-mapping>中添加0~n个<dispatcher>子元素,来说明当前访问的拦截方式:

<!-- 拦截对b.jsp的请求、转发操作  -->
<filter-mapping>
	<filter-name>myfilter</filter-name>
	<url-pattern>/b.jsp</url-pattern>
	<dispatcher>REQUEST</dispatcher>
	<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<!-- 没有给出拦截方式,那么默认为:REQUEST  -->
<filter-mapping>
	<filter-name>myfilter</filter-name>
	<url-pattern>/b.jsp</url-pattern>
</filter-mapping>
<!-- 给出了拦截方式为FORWARD,那么则只拦截FORWARD,而不拦截REQUEST  -->
<filter-mapping>
	<filter-name>myfilter</filter-name>
	<url-pattern>/b.jsp</url-pattern>
	<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<!-- ERROR拦截方式的配置  -->
<filter-mapping>
	<filter-name>myfilter</filter-name>
	<url-pattern>/b.jsp</url-pattern>
	<dispatcher>ERROR</dispatcher>
</filter-mapping>
<error-page>
	<error-code>500</error-code>
	<location>/b.jsp</location>
</error-page>

五、多个Filter的执行顺序

 多个过滤器的执行顺序是由<filter-mapping>在web.xml文件中配置的顺序决定的。

<filter>
	<filter-name>myFilter1</filter-name>
	<filter-class>cn.practice.filter.MyFilter1</filter-class>
<filter>
<filter-mapping>
	<filter-name>myFilter1</filter-name>
	<url-pattern>/index.jsp</url-pattern>
</filter-mapping>
<filter>
  	<filter-name>myFilter2</filter-name>
  	<filter-class>cn.practice.filter.MyFilter2</filter-class>
</filter>
<filter-mapping>
  	<filter-name>myFilter2</filter-name>
  	<url-pattern>/index.jsp</url-pattern>
</filter-mapping>

六、过滤器的应用场景

  • 执行目标资源之前做预处理工作:
    例如设置编码,这种试通常都会放行,只是在目标资源执行之前做一些准备工作;
  • . 通过条件判断是否放行:
    例如校验当前用户是否已经登录,或者用户IP是否已经被禁用;
  • . 在目标资源执行后,做一些后续的特殊处理工作:
    例如把目标资源输出的数据进行处理;
发布了31 篇原创文章 · 获赞 97 · 访问量 26万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览