我的初恋女友----------Filter



一、什么是Web Filter?


    Web Filter 是web开发中的一种过滤器。说道过滤器,顾名思义,就是用来过滤东西的嘛!生活中也有


非常多得例子,比如:自来水过滤器,化学实验室滤纸也是一种过滤器。


    在 web 中,服务器处理的都是用户的各种请求,并作出相应的响应!我们不妨设想一下,在一个超级


大型的web网站应用中,加入用户请求的一个html页面、jsp页面不存在,那么服务器端肯定会报出相应的


404异常(见下图)。

wKioL1gglVig_JsCAAB6689xzGY974.png



    如果此时不加以任何修改,直接将下图呈现给用户,那么这对用户来说是非常不友好的,再者用户也有


可能看不懂图中所表示的信息是什么。


    此时我们就可以通过过滤器,将所有404的错误以一个友好的界面呈现给用户。



二、Filter 在 Java EE API 中的位置。


    Filter 技术相关的接口存放于 Java EE API 的javax.servlet包下。


    1、相关的接口


        Filter、FliterChain、FilterConfig、FilterRegistration、FilterRegistration.Dynamic



三、如何创建一个Filter?


    在 web 应用中,所有的过滤器都需要实现 javax.servlet.Filter 接口,并实现该接口定义的以下三


个方法:

1、     void init(FilterConfig filterConfig) throws ServletException

2、     void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)
        throws IOException,ServletException
        
3、     void destroy()


第1个方法:init()

    

    该方法在web 容器加载web应用时执行,并且整个web应用生命周期只执行一次,如果重新部署web应


用,则该方法会重新执行。


第2个方法:doFilter()

    

    该方法是过滤器的核心操作,也就是具体实现过滤的操作。当用户访问请求与过滤器关联的URL时,web


容器就会调用该方法,FilterChain 类型的参数可以调用chain.doFilter()方法,将请求转发给下一个过滤


器,同时我们也可以利用请求转发、重定向到相应的资源。


第3个方法:destory()


    该方法在web应用被销毁时自动执行。



以下是一个简单的未实现任何操作的过滤器代码:

/*一个普通的java类实现了javax.servlet.Filter接口就会变成一个Filter,并自动实现三个生命周期方法*/
public class FirstFilter implements Filter {

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		//该方法只会在web应用被销毁时执行
	}

	@Override
	public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
			throws IOException, ServletException {
		// TODO Auto-generated method stub
		//过滤器的核心操作
		arg2.doFilter(arg0, arg1);
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
		// TODO Auto-generated method stub
		/*
		 * 1、该方法只会执行一次
		 * 2、可以通过FilterConfig类型参数 arg0 获取到该Filter 的相关初始化参数
		 * 3、也可以通过该参数获取到ServletContext上下文,通过该上下文可以获取到该web应用的几乎所有信息
		 */
	}
}


在传统的web开发中,我们创建完过滤器一般都需要在web.xml文件中进行相应的配置:


<filter>
		<!-- 该名字可以自定义取 -->
		<filter-name>FirstFilter</filter-name>
		<!-- 对应的过滤器类,要写上包名.类名 -->
		<filter-class>com.filters.FirstFilter</filter-class>
	</filter>
	
	<filter-mapping>
		<!-- 该名字一定要和上面相同 -->
		<filter-name>FirstFilter</filter-name>
		<!-- 定义该过滤器过滤的路径,/*表示过滤所有路径,该值可以取多个,以逗号隔开 -->
		<url-pattern>/*</url-pattern>
	</filter-mapping>

   

在Java EE 7 中允许我们使用注解的方式声明一个过滤器,以下是实例:


/*
*只需加上@WebFilter注解即可,并制定相应的过滤路径及初始化参数
*1、以下代表过滤所有的路径,即所有用户请求的web资源都要经过该过滤器
*2、filterName:指定Filter的名字
*3、指定初始化参数(可以多个初始化参数,每一个初始化参数都是一个@WebInitParam注解)
*/
@WebFilter(filterName = "FirstFilter",urlPatterns = {"/*"},initParams = {@WebInitParam(name = "mood", value = "awake")})
public class FirstFilter implements Filter {

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		//该方法只会在web应用被销毁时执行
	}

	@Override
	public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
			throws IOException, ServletException {
		// TODO Auto-generated method stub
		//过滤器的核心操作
		arg2.doFilter(arg0, arg1);
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
		// TODO Auto-generated method stub
		/*
		 * 1、该方法只会执行一次
		 * 2、可以通过FilterConfig类型参数 arg0 获取到该Filter 的相关初始化参数
		 * 3、也可以通过该参数获取到ServletContext上下文,通过该上下文可以获取到该web应用的几乎所有信息
		 */
	}
}