day17_Listener与Filter

一、Listener监听器(了解)

Javaweb开发中的监听器,是用于监听web常见对象的。
    例如web的常见对象有:ServletContext、HttpServletRequest、HttpSession
    监听它们的创建与销毁属性变化session绑定javaBean

1、监听机制

    事件:就是一个事情。
    事件源:产生这个事情的源头。
    监听器:用于监听指定的事件的对象。(关联事件和事件源)
    注册监听:要想让监听器可以监听到事件产生,必须对其进行注册。

2、Javaweb开发中常见监听器

  2.1、监听域对象的创建与销毁

    若要监听ServletContext对象的创建与销毁       则需要写一个监听器类实现 ServletContextListener 接口
    若要监听HttpSession对象的创建与销毁         则需要写一个监听器类实现 HttpSessionListener 接口
    若要监听HttpServletRequest对象的创建与销毁     则需要写一个监听器类实现 ServletRequestListener 接口

  2.2、监听域对象的属性变化

    若要监听ServletContext对象的属性变化       则需要写一个监听器类实现 ServletContextAttributeListener 接口
    若要监听HttpSession对象的属性变化         则需要写一个监听器类实现 HttpSessionAttributeListener 接口
    若要监听HttpServletRequest对象的属性变化     则需要写一个监听器类实现 ServletRequestAttributeListener 接口

  2.3、监听session绑定javaBean

    若要监听javaBean对象是否绑定到了session域     则需要写一个监听器类实现 HttpSessionBindingListener 接口
    若要监听javaBean对象的活化与钝化          则需要写一个监听器类实现 HttpSessionActivationListener 接口

3、监听器的快速入门

关于创建一个监听器的步骤:
    1. 创建一个监听器类,实现指定的监听器接口。
    2. 重写接口中的方法。
    3. 在web.xml文件中对监听器进行注册。

  3.1、关于域对象的创建与销毁的演示

    1. ServletContext对象的创建与销毁
      ServletContext对象是在服务器启动时创建的,在服务器关闭时销毁的。

package com.itheima.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class MyServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("ServletContext对象被创建了"); // 服务器一启动,ServletContext对象就被创建了
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("ServletContext对象被销毁了"); // 服务器一关闭,ServletContext对象就被销毁了
}
}

    2. HttpSession对象的创建与销毁
      HttpSession session = request.getSession();
      Session的销毁方式:
        1.默认超时30分钟后销毁
        2.关闭服务器时销毁
        3.调用invalidate()方法
        4.setMaxInactiveInterval(int interval) 可以设置超时时间
      问题:直接访问一个jsp页面时,是否会创建Session?
        答:会创建,因为我们默认情况下是在jsp页面中直接使用Session内置对象的。

package com.itheima.listener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class MyHttpSessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println("HttpSession对象被创建了");
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("HttpSession对象被销毁了");
}
}

  index.jsp

  <body>
<%
session.invalidate(); // 手动使session销毁
%>

</body>

    3. HttpServletRequest对象的创建与销毁
      Request对象是发送请求时服务器就会去创建它,当响应产生时,request对象就会被销毁。

package com.itheima.listener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
public class MyServletRequestListener implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent sre) {
System.out.println("ServletRequest被销毁了");
}
@Override
public void requestInitialized(ServletRequestEvent sre) {
System.out.println("ServletRequest被创建 了");
}
}

  3.2、演示Request域对象中的属性变化

    在java的监听机制中,它的监听器中的方法都是有参数的,参数就是事件对象,而我们可以通过事件对象直接获取事件源。

package com.itheima.attributelistener;
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
public class MyServletRequestListener implements ServletRequestAttributeListener {
@Override
public void attributeAdded(ServletRequestAttributeEvent srae) {
System.out.println("ServletRequest添加属性了");
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent srae) {
System.out.println("ServletRequest移除属性了");
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent srae) { // 参数代表事件对象
System.out.println("ServletRequest替换属性了");
// srae.getServletRequest(); // 通过事件对象直接获取事件源
// System.out.println(srae.getName() + "\t" + srae.getValue()); // org.apache.catalina.ASYNC_SUPPORTED true
}
}

  index.jsp

  <body>
<%
// session.invalidate(); // 手动使session销毁
request.setAttribute("name", "tom");
request.setAttribute("name", "luna");
request.removeAttribute("name");
%>
</body>

  3.3、演示session绑定javaBean

    1.javaBean对象自动感知被绑定到session中
      HttpSessionBindingListener 这个接口是由javaBean实现的,并且不需要在web.xml文件中注册。

package com.itheima.domain;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
public class User implements HttpSessionBindingListener {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public void valueBound(HttpSessionBindingEvent event) {
System.out.println("向session中绑定了一个user对象");
}
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
System.out.println("从session中将user对象移除");
}
}

  index.jsp

  <body>
<%
// session.invalidate(); // 手动使session销毁
// request.setAttribute("name", "tom");
// request.setAttribute("name", "luna");
// request.removeAttribute("name");
User user = new User();
user.setName("luna");
user.setAge(25);
// 绑定到session
session.setAttribute("u", user);
// 解除绑定
session.removeAttribute("u");
%>
</body>

    2.javabean对象可以活化或钝化到session中
      HttpSessionActivationListener,如果javaBean实现了这个接口,那么当我们正常关闭服务器时,session中的javaBean对象就会被钝化到我们指定的文件中。
      当下一次再启动服务器,因为我们已经将对象写入到文件中,这时就会自动将javaBean对象活化到session中。

package com.itheima.domain;
import java.io.Serializable;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import javax.servlet.http.HttpSessionEvent;
public class User implements Serializable, HttpSessionBindingListener, HttpSessionActivationListener {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public void valueBound(HttpSessionBindingEvent event) {
System.out.println("向session中绑定了一个user对象");
}
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
System.out.println("从session中将user对象移除");
}
@Override
public void sessionDidActivate(HttpSessionEvent se) {
System.out.println("钝化");
}
@Override
public void sessionWillPassivate(HttpSessionEvent se) {
System.out.println("活化");
}
}

  我们还需要个context.xml文件来配置钝化时存储的文件,在META-INF目录下创建一个context.xml文件,输入以下代码:

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

4、监听器的案例

    4.1、案例1_定时销毁session

  1. 怎样可以将每一个创建的session全都保存起来呢?
    答:我们可以做一个HttpSessionListener,当session对象创建时,就将这个session对象装入到一个集合中,然后将集合List<HttpSession>保存到ServletContext域中。
  2. 怎样可以判断session过期了?
    答:在HttpSession中有一个方法public long getLastAccessedTime(),它可以得到session对象最后使用的时间。然后可以使用invalidate方法销毁

    我们上面的操作需要使用任务调度功能。

猜你喜欢

转载自www.cnblogs.com/chenmingjun/p/9119641.html