您的位置:首页 > 编程语言 > Java开发

过滤器,监听器和struts2拦截器

2016-11-18 14:54 239 查看
貌似是老生常谈了,但我相信还是有很多初学者不知道他们的区别,今天在此再做一个小结,来说说他们各自的特点以及相互之间的区别。

过滤器:

 当客户端发出Web资源的请求时,Web服务器根据应用程序配置文件设置的过滤规则进行检查,若客户请求满足过滤

规则,则对客户请求/响应进行拦截,对请求头和请求数进行检查或改动,并依次通过过滤器链,最后把请求/响

应交给请求的Web资源处理。请求信息在过滤器链中可以被修改,也可以根据条件让请求不发往资源处理器,并直接

向客户机发回一个响应。当资源处理器完成了对资源的处理后,响应信息将逐级逆向返回。同样在这个过程中,用户

可以修改响应信息,从而完成一定的任务。那么当两个过滤器同时过滤一个请求时谁先谁后呢?这就涉及到了过滤链

FilterChain。所有的奥秘都在Filter的FilterChain中。服务器会按照web.xml中过滤器定义的先后循序组装成一条链,

然后一次执行其中的doFilter()方法。执行的顺序就如下图所示,执行第一个过滤器的chain.doFilter()之前的代码,第

二个过滤器的chain.doFilter()之前的代码,请求的资源,第二个过滤器的chain.doFilter()之后的代码,第一个过滤器

的chain.doFilter()之后的代码,最后返回响应。



通常我们所访问的资源是一个servlet或jsp页面,而jsp其实是一个被封装了的servlet,于是我们就可以统一地认为

我们每次访问的都是一个Servlet,而每当我们访问一个servlet时,web容器都会调用该Servlet的service方法去处理

请求。而在service方法又会根据请求方式的不同(Get/Post)去调用相应的doGet()或doPost()方法,实际处理请

求的就是这个doGet或doPost方法。写过servlet的朋友都应该知道,我们在doGet(或doPost)方法中是通过

response.getWriter()得到客户端的输出流对象,然后用此对象对客户进行响应。

       到这里我们就应该理解了过滤器的执行流程了:执行第一个过滤器的chain.doFilter()之前的代码——>第二个

过滤器的chain.doFilter()之前的代码——>……——>第n个过滤器的chain.doFilter()之前的代码——>所请求

servlet的service()方法中的代码——>所请求servlet的doGet()或doPost()方法中的代码——>第n个过滤器的

chain.doFilter()之后的代码——>……——>第二个过滤器的chain.doFilter()之后的代码——>第一个过滤器的

chain.doFilter()之后的代码。

过滤器生命周期的四个阶段:

1、实例化:Web容器在部署Web应用程序时对所有过滤器进行实例化。Web容器回调它的无参构造方法。2、初始化:实例化完成之后,马上进行初始化工作。Web容器回

调init()方法。

3、过滤:请求路径匹配过滤器的URL映射时。Web容器回调doFilter()方法——主要的工作方法。

4、销毁: Web容器在卸载Web应用程序前,Web容器回调destroy()方法。

监听器:

监听你的web应用,监听许多信息的初始化,销毁,增加,修改,删除值等

Servlet监听器用于监听一些重要事件的发生,监听器对象可以在事情发生前、发生后可以做一些必要的处理。

1.Listener是Servlet的监听器

2.可以监听客户端的请求、服务端的操作等。

3.通过监听器,可以自动激发一些操作,如监听在线用户数量,当增加一个HttpSession时,给在线人数加1。

4.编写监听器需要实现相应的接口

5.编写完成后在web.xml文件中配置一下,就可以起作用了

6.可以在不修改现有系统基础上,增加web应用程序生命周期事件的跟踪

servlet 规范中为每种事件监听器都定义了相应的接口,在编写事件监听器程序时只需实现这些接口就可以了。一些Servlet事件监听器需要在web应用程序的部署 文件描述符文件(web.xml)中进行注册(注册之后才能发布),一个web.xml可以注册多个servlet事件监听器。web服务器按照它们在web.xml中注册顺序来加载和注册这些servlet事件监听器。servlet事件监听器的注册和调用过程都是由web容器自动完成的,当发生被监听对象被创建,修改,销毁等事件时,web容器将调用与之相关的servlet事件监听器对象的相应方法(所监听到的对象如果在创建、修改、销毁事件触发的时候就会调用这些监听器这就相当于面向事件编程的概念),用户在这些方法中编写的事件处理代码(相当于JS中的事件响应)即被执行。由于在一个web应用程序中只会为每个事件监听器类创建一个实例对象,有可能出现多个线程同时调用一个事件监听对象的情况,所以要注意多线程安全问题。

二、监听器类型


按监听的对象划分:servlet2.4规范定义的事件有三种:

1.用于监听应用程序环境对象(ServletContext)的事件监听器

2.用于监听用户会话对象(HttpSession)的事件监听器

3.用于监听请求消息对象(ServletRequest)的事件监听器

当然还有很多分类方式,在此不做赘述。

struts2拦截器

拦截器(interceptor)是Struts2最强大的特性之一,也可以说是struts2的核心,拦截器可以让你在Action和result被执行之前或之后进行一些处理。同时,拦截器也可以让你将通用的代码模块化并作为可重用的类。Struts2中的很多特性都是由拦截器来完成的。拦截是AOP的一种实现策略。在Webwork的中文文档的解释为:拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行。同时也是提供了一种可以提取action中可重用的部分的方式。谈到拦截器,还有一个词大家应该知道——拦截器链(Interceptor
Chain,在Struts 2中称为拦截器栈Interceptor Stack)。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。

拦截器的实现原理:

大部分时候,拦截器方法都是通过代理的方式来调用的。Struts 2的拦截器实现相对简单。当请求到达Struts 2的ServletDispatcher时,Struts 2会查找配置文件,并根据其配置实例化相对的拦截器对象,然后串成一个列表(list),最后一个一个地调用列表中的拦截器。事实上,我们之所以能够如此灵活地使用拦截器,完全归功于“动态代理”的使用。动态代理是代理对象根据客户的需求做出不同的处理。对于客户来说,只要知道一个代理对象就行了。那Struts2中,拦截器是如何通过动态代理被调用的呢?当Action请求到来的时候,会由系统的代理生成一个Action的代理对象,由这个代理对象调用Action的execute()或指定的方法,并在struts.xml中查找与该Action对应的拦截器。如果有对应的拦截器,就在Action的方法执行前(后)调用这些拦截器;如果没有对应的拦截器则执行Action的方法。其中系统对于拦截器的调用,是通过ActionInvocation来实现的。Interceptor的接口定义没有什么特别的地方,除了init和destory方法以外,intercept方法是实现整个拦截器机制的核心方法。而它所依赖的参数ActionInvocation则是著名的Action调度者。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  struts2.0 框架 J2EE