Listener和Filter学习笔记

Filter和Listener是Servlet规范里的两个高级特性,可认为是servlet的一种“加强版”。它们不同于servlet,Filter不进行处理客户端请求,只是对用户请求进行预处理,也可对响应进行后处理,或者是对context、session、request事件进行监听。很好地使用这两个高级特性可轻松解决一些特殊问题。

一、过滤器Filter

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

ServletFilte体现的是设计模式中的Filter模式。一个FilterChain包括多个Filter,请求是在抵达Servlet之前会经过FilterChain里的所有Filter,响应也会在抵达客户端浏览器之前经过FilterChain里的所有Filter。一个Filter必须实现javax.servlet.Filter接口,该接口中定义了三个方法:init(),destroy(),doFilter(),要实现过滤功能,就要对每个请求响应增进行外的处理,这三个方法也反映了Filter的生命周期,其中init()和destroy()方法只会被调用一次,分别在web程序加载或者卸载的时候调用。转载doFilter()方法每次有客户端请求都会被调用一次。Filter所有工作都集中在doFilter()方法中了。Filter可以拦截多个请求或响应,一个请求或响应也可被多个Filter拦截。

Filter有如下几种用途:

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

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

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

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

Filter有如下几类:

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

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

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

XSLT Filter,Gzip压缩Filter等

 Filter的使用配置: 自定义的Filter需要实现Filter接口,将自己的逻辑写入到doFilter中,如 chain.doFilter(request,response);

像servlet一样,类似的配置如下:

<filter>

        <filter-name>myfilter</filter-name>
        <filter-class>com.demo.filter.MyFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>myfilter</filter-name>
        <url-pattern>/*</url-pattern> 

       </filter-mapping> 

在<filter-mapping>里有个 <dispatcher>配置,其配置到达Servlet的方式,有4种取值:REQUEST,FORWARD,INCLUDE,ERROR,可以同时配置多个<dispatcher>,如果没有配置默认使用REQUEST,它们的区别如下:

 REQUEST:表示仅当直接请求Servlet时才生效

FORWARD:表示仅当某Servlet通过forward到该Servlet时才生效

INCLUDE:JSP中可以通过<jsp:include/>请求某Servlet,仅这种情况下有效

ERROR:JSP中可以通过<%@ page errorPage="error.jsp" %>指定错误处理页面,仅在这种情况下才有效。

另外,<url-pattern>与<dispatcher>的关系是“且” 的关系,只有两者都满足了,Filter才能生效。Filter的配置是有先后顺序的,配置在前的早于后面的执行,而且多个Filter之间会相互影响。

 

二)监听器Listener

 Listener用于监听java web程序中的事件,例如创建、修改、删除Session、Request、Context等,并触发相应的事件,Servlet提供了大量的监听器API,Listener对象设计模式中的Listener模式。

使用相应的Listener需要实现相应的Listener接口,当事件发生的时候会自动触发该事件对应的Listener。servlet规范中有8种Listener,分别用于监听Request、Session、 Context等创建与销毁、属性变化等,而且还可以监听Session中的对象。

ServletContextListener:用于监听Web应用的启动和关闭,ContextInitialized,ContextDestroyed

HttpSession Listener:用于监听用户Session的开始和结束,sessionCreated,sessionDestroyed

ServletRequestListener:用于监听用户请求,requestInitialized,requestDestroyed

另外还有三个监听器用于监听对象的属性变化,有ServletRequestAttributeListener ,HttpSessionAttributeListener,ServletContextAttributeListener ,当想被监听的对象中添加、删除、更新属性时,会分别执行xxxAdded(),xxxReplaced(),xxxRemoved()方法。

HttpSessionBindingListener与HttpSessionActivationListener用来监控Session内的对象,它们的触发时机分别为:

HttpSessionBindingListener:当对象被放到Session里是执行valueBound()方法,当对象被从Session里移除时执行valueUnbound()方法。HttpSessionActivationListener:服务器关闭时,会将Session里的内容保存到硬盘上,这个过程叫钝化,服务器重新启动时,会将Session内容从硬盘上重新加载,当Session里的对象被钝化时会执行sessionWillPassivate()方法,当对象被重新加载时执行sessionDidActivate()方法。 对象必须实现Listener接口。

 我们使用Listener时仍然需要配置:

<listener>

        <listener-class>com.demo.listener.RequestListenerTest</listener-class>

</listener> 

Listener和Filter与Servlet、JSP等没有业务耦合, 可自由拆卸,合理设计Listener和Filter会使程序更高效!

 

 

posted on 2012-12-29 16:28  糊涂先生  阅读(480)  评论(0编辑  收藏  举报