JavaWeb学习之Listener&Filter

Listener(监听器)

> 监听某个事件的发生,其内部机制就是接口回调

一、接口回调

* 需求:
> A在执行循环,当循环到5的时候, 通知B。
> 事先先把一个对象传递给 A , 当A 执行到5的时候,通过这个对象,来调用B中的方法。
> 但是注意,不是直接传递B的实例,而是传递一个接口的实例过去。

二、Web监听器

### 使用监听器的步骤:
1. 定义一个类,实现接口
  如:MyServletContextListener implements ServletContextListener
2. 注册 | 配置监听器
  配置文件路径:WebContent/WEB-INF/web.xml
<listener>
<listener-class>实现监听器接口的类的全名称(xx.xxx.xxxx.MyServletContextListener)</listener-class>
</listener>

### 总共有8个 划分成三种类型

Ⅰ、监听三个作用域创建和销毁

作用域有:

  pageContext  --- 当前页面

  request --- httpServletRequest

  session --- httpSession

  application --- ServletContext

1、ServletContextListener(application作用域):用于监听ServletContext的创建和销毁

  servletcontext创建: 启动服务器的时候

  servletContext销毁:关闭服务器. 从服务器移除项目

2、ServletRequestListener(request作用域):用于监听Request的创建和销毁

  request创建:访问服务器上的任意资源都会有请求出现。

        访问 html: 会
        访问 jsp: 会
        访问 servlet : 会

  request销毁:服务器已经对这次请求作出了响应。

3、HttpSessionListener(Session作用域):用于监听Request的创建和销毁

  session的创建:只要调用getSession

        html:不会
        jsp:会   默认调用getSession();
        servlet::会(必须在代码中调用getSession())

  session的销毁:超时(一般情况30分钟)、服务器非正常关闭

作用:

  ServletContextListener

    1. 完成自己想要的初始化工作

    2. 执行自定义任务调度。 执行某一个任务。

  HttpSessionListener

    统计在线人数

Ⅱ、 监听三个作用域属性状态变更

### 可以监听在作用域中值 添加  | 替换  | 移除的动作。

1、servletContext --- ServletContextAttributeListener

2、request --- ServletRequestAttributeListener

3、session --- HttpSessionAttributeListener

session.setAttribute("name","zhangsan");//attributeAdded方法监听

session.setAttribute("name","lisi");//attributeReplaced方法监听

session.removedAttribute("name");//attributeRemoved方法监听

Ⅲ、监听httpSession里面值的状态变更

这一类监听器不用注册

  1、HttpSessionBindingListener:监听对象与session 绑定和解除绑定 的动作

    让javaBean 实现该接口即可

			@Override
			public void valueBound(HttpSessionBindingEvent event) {
				System.out.println("对象被绑定进来了");
			}
		
			@Override
			public void valueUnbound(HttpSessionBindingEvent event) {
				System.out.println("对象被解除绑定");
			}

    javaBean对象存放到session中

session.setAttribute(javaBean对象);
session.removedAttribute(javaBean对象);

 

  2、HttpSessionActivationListener:用于监听现在session的值 是 钝化 (序列化)还是活化 (反序列化)的动作

    钝化 (序列化):把内存中的数据 存储到硬盘上

    活化 (反序列化):把硬盘中的数据读取到内存中。

    实例:

      服务器正常关闭,会使Session钝化,服务器启动Session活化

        ①、JavaBean实现HttpSessionActivationListener和Serialzable(用于序列化和反序列化,不实现此接口就无法把硬盘数据读到存储中)

public class Bean02 implements HttpSessionActivationListener,Serialzable{
	private String name;
	
	public String getName(){
		return name;
	}
	
	public void setName(String name){
		this.name = name;
	}
	
	@Override
	public void sessionWillPassivate(HttpSessionEvent se){
		System.out.println("Session中的值(Bean02对象)被钝化了...")
	}
	
	@Override
	public void sessionDidActivate(HttpSessionEvent se){
		System.out.println("Session中的值(Bean02对象)被活化了...")
	}
}

        ②、session存储JavaBean对象

<%
Bean02 bean = new Bean02();
bean.setName("xiaoxiao");
session.setAttribute("sessionkey_bean",bean);
%>

        ③、获取session中的数据

<%
sessionkey_bean.getName()
%>

可以通过正常关闭服务器测试。

        ④、通过配置让session在一定时间内钝化

          在tomcat里面 conf/context.xml 里面配置:对所有的运行在这个服务器的项目生效

          在conf/Catalina/localhost/context.xml 配置:对 localhost生效(localhost:8080)

          在自己的web工程项目中的 META-INF/context.xml:只对当前的工程生效

          配置内容:

		<Context>
			<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
				<Store className="org.apache.catalina.session.FileStore" directory="xxx"/>
			</Manager>
		</Context> 

maxIdleSwap : 1分钟不用就钝化
directory :  钝化后的那个文件存放的目录位置。(\tomcat\apache-tomcat-7.0.52\work\Catalina\localhost\项目名\xxx(directory的值))

Filter(过滤器)

  > 其实就是对客户端发出来的请求进行过滤。 浏览器发出, 然后服务器派servlet处理。  在中间就可以过滤, 其实过滤器起到的是拦截的作用

一、使用Filter

  1、定义一个类, 实现Filter接口

		public class FilterDemo implements Filter {

			public void destroy() {
			}
		
			public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
				System.out.println("来到过虑器了。。。");
				chain.doFilter(request, response);
			}
		
			public void init(FilterConfig fConfig) throws ServletException {
			}
		
		}

  2、注册过滤器

		  <filter>
		    <display-name>FilterDemo</display-name>
		    <filter-name>FilterDemo</filter-name>
		    <filter-class>com.itheima.filter.FilterDemo</filter-class>
		  </filter>
		  <filter-mapping>
		    <filter-name>FilterDemo</filter-name>
		    <url-pattern>/*</url-pattern>
		  </filter-mapping>

二、Filter的生命周期

  * 创建:服务器启动

  * 销毁:服务器停止

三、Filter执行顺序

  1、客户端发出请求,先经过过滤器, 如果过滤器放行,那么才能到servlet

  2、如果有多个过滤器, 那么他们会按照注册的映射顺序(<filter-mapping>的顺序)。 只要有一个过滤器不放行,那么后面排队的过滤器以及咱们的servlet都不会收到请求

		  <filter>
		    <display-name>FilterDemo</display-name>
		    <filter-name>FilterDemo</filter-name>
		    <filter-class>com.itheima.filter.FilterDemo</filter-class>
		  </filter>
		  <filter>
		    <display-name>FilterDemo02</display-name>
		    <filter-name>FilterDemo02</filter-name>
		    <filter-class>com.itheima.filter.FilterDemo02</filter-class>
		  </filter>
		  <filter>
		    <display-name>FilterDemo03</display-name>
		    <filter-name>FilterDemo03</filter-name>
		    <filter-class>com.itheima.filter.FilterDemo03</filter-class>
		  </filter>
		  <filter>
		    <display-name>FilterDemo04</display-name>
		    <filter-name>FilterDemo04</filter-name>
		    <filter-class>com.itheima.filter.FilterDemo04</filter-class>
		  </filter>

		  <filter-mapping>
		    <filter-name>FilterDemo04</filter-name>
		    <url-pattern>/*</url-pattern>
		  </filter-mapping>
		  <filter-mapping>
		    <filter-name>FilterDemo02</filter-name>
		    <url-pattern>/*</url-pattern>
		  </filter-mapping>
		  <filter-mapping>
		    <filter-name>FilterDemo03</filter-name>
		    <url-pattern>/*</url-pattern>
		  </filter-mapping>
		  <filter-mapping>
		    <filter-name>FilterDemo</filter-name>
		    <url-pattern>/*</url-pattern>
		  </filter-mapping>

1、chain.doFilter(request, response); 放行, 让请求到达下一个目标   

2、<url-pattern>/*</url-pattern>

  全路径匹配  以 /  开始( /LoginServlet   访问LoginServlet,执行过滤器)

  以目录匹配 以 / 开始  以 * 结束 (/demo01/*  访问demo01文件夹下的文件,执行过滤器)

  以后缀名匹配  以 * 开始 以后缀名结束(*.jsp  *.html *.do  访问具体的文件类型,执行过滤器)

3、dispatcher 设置

		<filter-mapping>
			<filter-name>FilterDemo</filter-name>
			<url-pattern>/*</url-pattern>
			
			<dispatcher>REQUEST</dispatcher>
			<dispatcher>FORWARD</dispatcher>
		</filter-mapping>

  REQUEST:只要是请求过来,都拦截,默认就是REQUEST

  FORWARD:只要是转发都拦截

  ERROR:页面出错发生跳转

  INCLUDE:包含页面的时候就拦截

 

 

posted @ 2020-08-04 17:09  一杯水M  阅读(206)  评论(0编辑  收藏  举报