过滤器和监听器

过滤器

什么是过滤器

· 过滤器是Servlet2.3规范中定义的一种小型的、可插入的Web组件。用来拦截Servlet容器的请求和响应过程,以便查看、提取或以某种方式操作正在客户机和服务器之间交换的数据

· 过滤器通常是封装了一些功能的Web组件,这些功能很重要,但对于处理客户端请求或发送响应来说不是决定性的;

· 典型的应用包括记录请求和响应的数据、管理会话属性等;

如何编写过滤器

(1)编写Java类,实现Filter类,在doFilter方法中实现拦截处理逻辑
/**
 * @author dream-it
 * 1.Filter用来处理多个请求之间的共性业务。
 * 	  如记录日志、过滤敏感词等。
 * 2.使用Filter解决问题不用修改任何Servlet,
 *   只需要新建Filter并配置即可,可以极大程度的
 *   降低业务代码和Servlet之间的耦合度。
 */
public class FirstFilter implements Filter {
	/**
	 * 在tomcat关闭时自动销毁
	 */
	public void destroy() {
		System.out.println("销毁FirstFilter");
	}

	public void doFilter(ServletRequest req, ServletResponse res,
			FilterChain chain) throws IOException, ServletException {
		System.out.println("FirstFilter前");
		//调用doFilter()是让请求继续执行,若没有调用此方法则请求中断,直接响应。
		//请求继续执行会调用后续的Filter,并最终调用Servlet
		//在此过程中Filter与Filter之间是有序调用的,
		//并且任何Filter将请求中断,都会导致后续的Filter无法执行,
		//他们的关系像链条一样,环环相扣。因此该对象叫做过滤连FilterChain
		//详见过滤器调用过程图
		chain.doFilter(req, res);
		System.out.println("FirstFilter后");		
	}

	/**
	 * Filter在tomcat启动是只创建初始化一次,所以它是单例的。
	 * 由别人创建的对象基本都是单例的。
	 */
	public void init(FilterConfig arg0) throws ServletException {
		System.out.println("初始化FirstFilter");
	}
(2)将过滤器添加Web应用中

    · 修改web.xml文件,增加注册过滤器的节点

 <!-- 声明Filter -->
  <filter>
  	<filter-name>first</filter-name>
  	<filter-class>web.FirstFilter</filter-class>
  </filter>
  <!-- 声明此Filter可以过滤/拦截那些请求 -->
  <filter-mapping>
  	<filter-name>first</filter-name>
  	<!-- 可以拦截的Servlet的访问路径,如果写出/*就表示一切 -->
  	<url-pattern>/*</url-pattern>
  </filter-mapping>
(3)过滤器和Web应用一起打包部署

    · 与Web应用程序一起部署过滤器时,只需把过滤器类和其他Web组件类包括在一起;把web.xml文件(连同过滤器注册)放进web应用程序结构中,Servlet容器将处理之后的其他事情;

过滤器的执行流程

过滤器的优先级

· 如果有多个过滤器都满足过滤的条件,则容器依据<filter-mapping>的先后顺序来调用各个过滤器

<filter>...</filter>
<filter>...</filter>

<filter-mapping>...</filter-mapping>
<filter-mapping>...</filter-mapping>

多个过滤器的执行流程

过滤器的初始化参数

· 容器启动之后,会创建过滤器实例;

· 接下来,容器会调用过滤器的init方法,而容器会事先创建FilterConfig对象。该对象可以访问web.xml文件中配置一些参数;

· 这些在web.xml文件中存储,由FilterConfig对象读取;

· 通过这些初始化参数可以方便快捷的配置及修改一些辅助参数;

初始化参数的配置
<filter>
  	<filter-name>filter</filter-name>
  	<filter-class>web.xxxFilter</filter-class>
  	<!-- 给当前的filter预置一个参数 -->
  	<init-param>
  		<param-name>city</param-name>
  		<param-value>北京</param-value>
  	</init-param>
  </filter>
  <filter-mapping>
  	<filter-name>filter</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>
读取初始化参数

· 使用FilterConfig对象可以读取在web.xml中配置初始化参数

String config.getInitParamter("city");

过滤器的优点

· 实现代码的“可插拔性”,即增加或减少某个功能模块,不会影响程序的正常执行;

· 可以将多个相同处理逻辑的模块集中写在过滤器里面,方便代码的维护;

监听器

什么是监听器

· Servlet规范中定义的一种特殊的组件,用来监听Servlet容器产生的事件进行相应的处理

· 容器产生的两大类事件:

  - 生命周期相关事件;

  - 绑定数据相关事件;

生命周期相关事件

· 容器创建或者销毁request、session、ServletContext时产生的事件;

· ServletRequestListener

requestDestroyed(ServletRequestEvent sre);
requestInitialized(ServletRequestEvent sre);

· HttpSessionListener

sessionCreated(HttpSessionEvent se);
sessionDestroyed(HttpSessionEvent se);

· ServletContextListener

contextDestroyed(ServletContextEvent sce);
contextInitialized(ServletContextEvent sce);

注:实现不同的接口会有不同的实现;

绑定数据相关事件

· 调用request、session、ServletContext的setAttribute、removeAttribute方法时产生的事件

· ServletRequestAttributeListener

attributeAdded(ServletRequestAttributeEvent srae);
attributeRemoved(ServletRequestAttributeEvent srae);
attributeReplaced(ServletRequestAttributeEvent srae);

· HttpSessionAttributeListener

  - 参考API文档

· ServletContextAttributeListener

  - 参考API文档

如何编写监听器

(1)编写一个Java类,依据监听事件类型选择实现相应的监听接口。如:要监听Session对象的创建和销毁,就要实现HttpSessionListener;
(2)在监听接口方法中,实现相应的监听处理逻辑;
public class MyListener implements HttpSessionListener,
		HttpSessionAttributeListener {

	public void sessionCreated(HttpSessionEvent e) {
		System.out.println("session创建");
		System.out.println(e.getSession());
	}

	public void sessionDestroyed(HttpSessionEvent arg0) {
		System.out.println("session销毁");
	}

	public void attributeAdded(HttpSessionBindingEvent arg0) {
		System.out.println("向session添加数据");
	}

	public void attributeRemoved(HttpSessionBindingEvent arg0) {
		
	}

	public void attributeReplaced(HttpSessionBindingEvent arg0) {
		
	}

}
(3)在web.xml文件中注册该监听器;
 <listener>
  	<listener-class>web.MyListener</listener-class>
  </listener>

注意:实现相同的Listener接口的多个监听器,在执行的时候按照web.xml注册出现的顺序来决定;

应用场景

· 由于ServletRequest、HttpSession、ServletContext对象都是容器创建的,通过对这些对象注册监听器,就可以得知何时创建了。比如:

1)在ContextDestroyed方法中对应用级别的资源进行释放;

2)统计在线人数可以通过HttpSessionListener监听器的sessionCreated方法监听session的创建动作;

Servlet上下文

什么是Servlet上下文

· 容器启动之后,会为每一个Web应用创建唯一的一个符合ServletContext接口要求的对象,该对象就是Servlet上下文;

· 特点

 - 唯一性(一个Web应用对应一个servlet);

 - 一直存在(只要容器不关闭,应用没有被卸载删除,servlet上下文就一直存在);

如何获取Servlet上下文

· 方式一

 - 通过GenericServlet提供的 getServletContext();

· 方式二

 - 通过ServletConfig提供的 getServletContext();

· 方式三

 - 通过HttpSession提供的 getServletContext();

· 方式四

 - 通过FilterConfig提供的getServletContext();

Servlet上下文的作用及特点

· 作用一

 - 使用setAttribute绑定数据;

· 作用二

 - 使用removeAttribute移除绑定数据;

· 作用三

 - 使用getAttribute获取绑定数据;

· 特点

 - servlet上下文绑定的数据可以被整个应用上的所有组件共享,并且可以一直访问;

猜你喜欢

转载自blog.csdn.net/huang_yx/article/details/80195605
今日推荐