天天看点

监听器Listener过滤器Filter总结

一、 监听器Listner

1. 监听器概述

监听器监听三大域,ServletRequest,HttpSession, ServletContext三大域,可以分别监听三大域的生命周期事件和属性事件,监听什么,就实现什么接口,覆写相关方法。当监听的事件发生改变时,会执行覆写的方法。

如:想要监听ServletContext域的属性添加事件和生命周期出生事件,编写MyServletContextListener类

  1. 实现ServletContextAttributeListener接口和ServletContextListener接口
  2. 覆写void attibuteAdded(ServletAttributeEvent event)方法和 void contextInitialized(ServletContxetEvent sce)方法。
  3. 在web.xml文件中部署监听器
<listener>
<listener-class>cn.itcast.listener.MyServletContextListener</listener-class>
</listener>
           
2. 监听器方法

由事件对象获得监听域对象

ServletContext servletContext = event.getServletConext();

由属性事件对象获得当前监听的域对象

3. 感知监听

1.HttpSession监听 :如JavaBean实现HttpSessionBindingListener接口,覆写以下两个方法,则可以监听javabean对象在session中的状态:

public void valueBound(HttpSessionBindingEvent event) 把监听器对象添加session中会调用监听器对象的本方法;

public void valueUnbound(HttpSessionBindingEvent event)方法,当把监听器对象移除到session中会调用监听器对象的本方法;

2.钝化 - HttpSessionActivationListener

Tomcat会在session从时间不被使用时钝化session对象,session中存储的对象也被纯化,当session被活化时,也会把session中存储的对象活化。

如果某个类实现了HttpSessionActiveationListener接口后,且实现Serializable接口当对象随着session被钝化和活化时,下面两个方法就会被调用:

public void sessionWillPassivate(HttpSessionEvent se):当对象感知被活化时调用本方法;

public void sessionDidActivate(HttpSessionEvent se):当对象感知被钝化时调用本方法;

二、 过滤器

1.什么是过滤器

过滤器JavaWeb三大组件之一,它与Servlet很相似!不它过滤器是用来拦截请求的,而不是处理请求的。

当用户请求某个Servlet时,会先执行部署在这个请求上的Filter,如果Filter“放行”(在doFilter()方法中添加chain.doFilter(request, response)),那么会继承执行用户请求的Servlet;如果Filter不“放行”,那么就不会执行用户请求的Servlet。

其实可以这样理解,当用户请求某个Servlet时,Tomcat会去执行注册在这个请求上的Filter,然后是否“放行”由Filter来决定。可以理解为,Filter来决定是否调用Servlet!当执行完成Servlet的代码后,还会执行Filter后面的代码。

Filter的三个方法:

l void init(FilterConfig):在Tomcat启动时被调用;

l void destroy():在Tomcat关闭时被调用;

l void doFilter(ServletRequest,ServletResponse,FilterChain):每次有请求时都调用该方法;

监听器Listener过滤器Filter总结
2.编写HelloFilter,对index.jsp进行拦截
  1. 实现Filter接口,覆写init(FilterConfig filterConfig),doFilter(ServletRequest request, ServletResponse response,FilterChain chain),destroy()方法。

不放行:

public class HelloFilter implements Filter {
	public void init(FilterConfig filterConfig) throws ServletException {}
	public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {
		System.out.println("Hello Filter");
	}
	public void destroy() {}
}
           

放行:

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...");
}
           
  1. 在web.xml文件中部署Filter
<filter>
   <filter-name>helloFilter</filter-name>
   <filter-class>cn.itcast.filter.HelloFilter</filter-class>
</filter>
<filter-mapping>
   <filter-name>helloFilter</filter-name>
   <url-pattern>/index.jsp</url-pattern>
</filter-mapping>
           
3.FilterConfig

ServletContext getServletContext():获取ServletContext的方法;

4. FilterChain

void doFilter(ServletRequest,ServletResponse):放行!表示执行下一个过滤器,或者执行目标资源。可以在调用FilterChain的doFilter()方法的前后添加语句,在FilterChain的doFilter()方法之前的语句会在目标资源执行之前执行,在FilterChain的doFilter()方法之后的语句会在目标资源执行之后执行。

如果当前过滤器是最后一个过滤器,那么调用chain.doFilter()方法表示执行目标资源,如果不是最后一个过滤器,那么chain.doFilter()表示执行下一个过滤器的doFilter()方法。

.

执行顺序

一个目标资源可以指定多个过滤器,过滤器的执行顺序是在web.xml文件中的部署顺序。

5. 四种拦截方式

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

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

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

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

如:

<filter-mapping>
	<filter-name>myfilter</filter-name>
	<url-pattern>/b.jsp</url-pattern>
	<dispatcher>REQUEST</dispatcher>
	<dispatcher>FORWARD</dispatcher>
</filter-mapping>
           
6. 过滤器的应用场景

执行目标资源之前做预处理工作,例如设置编码,这种试通常都会放行,只是在目标资源执行之前做一些准备工作;

通过条件判断是否放行,例如校验当前用户是否已经登录,或者用户IP是否已经被禁用;

在目标资源执行后,做一些后续的特殊处理工作,例如把目标资源输出的数据进行处理;

7. 案例
  1. 分ip统计网站的访问次数
  2. 粗粒度权限控制(拦截是否登录、拦截用户名admin权限)
  3. 解决全站字符乱码(POST和GET中文编码问题)
  4. 页面静态化
    监听器Listener过滤器Filter总结

继续阅读