监听器Listener

监听器Listener

一、监听器介绍

1.1监听器概念

监听器简单来说就是实现特定接口的普通的Java程序,这个程序专门用来监听另一个Java对象的方法调用或属性的改变,当被监听对象发生上述事件后,监听器的方法立刻执行。

二、JavaWeb中的监听器

2.1基本概念

JavaWeb中的监听器就是Servlet中的一种特殊的实现类,用于监听web应用程序中的ServletContext(application), HttpSession(session)和 ServletRequest(request)等域对象的创建与销毁事件,以及监听这些域对象中的属性发生修改的事件。

2.2 Servlet监听器的分类

监听的事件源分别为【ServletContext,HttpSession,ServletRequest】三个域中的对象。监听器按功能划分可分为三种类型:

  • 监听域对象自身的创建和销毁事件监听器。
  • 监听域对象中的属性的增加和删除的事件监听器。
  • 监听绑定到Session域中的某个对象的状态的事件监听器。

监听域对象的创建和销毁

编写一个普通的java程序实现ServletContextListener,HttpSessionListener,ServletRequestListener三个接口,并重写创建和销毁方法。

范例:编写一个Listener类,监听ServletContext,HttpSession,ServletRequest对象的创建和销毁。

1、编写监听器

public class Listener implements ServletContextListener, HttpSessionListener, ServletRequestListener {

@Override
public void contextInitialized(ServletContextEvent sce) {
    System.out.println("监听ServletContext,创建ServletContext对象..."+sce);
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
    System.out.println("监听ServletContext,销毁ServletContext对象..."+sce);
}

@Override
public void sessionCreated(HttpSessionEvent se) {
    System.out.println("监听HttpSession,创建HttpSession对象..."+se);
}

@Override
public void sessionDestroyed(HttpSessionEvent se) {
    System.out.println("监听HttpSession,销毁HttpSession对象..."+se);
}

@Override
public void requestInitialized(ServletRequestEvent sre) {
    System.out.println("监听ServletRequest,创建ServletRequest对象..."+sre);
}

@Override
public void requestDestroyed(ServletRequestEvent sre) {
    System.out.println("监听ServletRequest,销毁ServletRequest对象..."+sre);
    }
}

 

2、在web.xml文件中注册监听器

<listener>
    <listener-class>com.example.Listener.Listener</listener-class>
</listener>

 

监听对象属性的增加和删除

域对象中属性的变更的事件监听器就是用来监听 ServletContext, HttpSession, HttpServletRequest 这三个对象中的属性变更信息事件的监听器。

这三个监听器接口分别是ServletContextAttributeListener, HttpSessionAttributeListener,ServletRequestAttributeListener,这三个接口中都定义了三个方法来处理被监听对象中的属性的增加,删除和替换的事件。

编写监听器

程序范例:编写一个java程序监听域对象属性的增加,删除和替换。

public class AttritubeListener implements ServletContextAttributeListener, ServletRequestAttributeListener, HttpSessionAttributeListener {

@Override
public void attributeAdded(ServletRequestAttributeEvent srae) {
    String name = srae.getName();
    String value = (String) srae.getServletRequest().getAttribute("onepiece");
    System.out.println("正在【增加】的属性名:"+name+"正在【增加】的属性值:"+value);
}

@Override
public void attributeRemoved(ServletRequestAttributeEvent srae) {
    System.out.println("正在【删除】的属性名:"+srae.getName());
}

@Override
public void attributeReplaced(ServletRequestAttributeEvent srae) {
    String name = srae.getName();
    String value = (String)srae.getServletRequest().getAttribute("onepiece");
    System.out.println("正在【替换】的属性名:"+name+"正在【替换】的属性值"+value);
}

@Override
public void attributeAdded(HttpSessionBindingEvent event) {
    String name = event.getName();
    String value = (String) event.getSession().getAttribute("onepiece");
    System.out.println("正在【增加】的属性名:"+name+"正在【增加】的属性值:"+value);
}

@Override
public void attributeRemoved(HttpSessionBindingEvent event) {
    System.out.println("正在【删除】的属性名:"+event.getName());

}

@Override
public void attributeReplaced(HttpSessionBindingEvent event) {
    String name = event.getName();
    String value = (String)event.getSession().getAttribute("onepiece");
    System.out.println("正在【替换】的属性名:"+name+"正在【替换】的属性值"+value);
}

@Override
public void attributeAdded(ServletContextAttributeEvent event) {
    String name = event.getName();
    String value = (String) event.getServletContext().getAttribute("onepiece");
    System.out.println("正在【增加】的属性名:"+name+"正在【增加】的属性值:"+value);
}

@Override
public void attributeRemoved(ServletContextAttributeEvent event) {
    System.out.println("正在【删除】的属性名:"+event.getName());
}

@Override
public void attributeReplaced(ServletContextAttributeEvent event) {
    String name = event.getName();
    String value = (String)event.getServletContext().getAttribute("onepiece");
    System.out.println("正在【替换】的属性名:"+name+"正在【替换】的属性值"+value);
    }
}

 

注册web.xml

<listener>
    <listener-class>com.example.Listener.AttritubeListener</listener-class>
</listener>

 

编写attritube.jsp测试监听结果

<body>
监听request域对象属性
<ul/>
<%

    request.setAttribute("onepiece","路飞");
    request.setAttribute("onepiece","索隆");
    request.removeAttribute("onepiece");

%>
监听session域对象属性
<ul/>
<%

    session.setAttribute("onepiece","路飞");
    session.setAttribute("onepiece","索隆");
    session.removeAttribute("onepiece");

%>

监听application域对象属性
<ul/>

<%
    application.setAttribute("onepiece","路飞");
    application.setAttribute("onepiece","索隆");
    application.removeAttribute("onepiece");
%>
</body>

 

程序运行结果

yyiuGj.jpg

感知Session绑定的事件监听器

保存在Session中的对象可以有多种状态:绑定到session中,从session中解绑;随session对象持久化到一个存储设备中(钝化到硬盘),随session对象从存储设备中恢复(活化到硬盘)

Servlet 规范中定义了两个特殊的监听器接口"【HttpSessionBindingListener和HttpSessionActivationListener"来帮助JavaBean 对象了解自己在Session域中的这些状态: ,实现这两个接口的类不需要 web.xml 文件中进行注册。】

程序范例:session的绑定解绑

/*
实现了HttpSessionBindingListener接口的 JavaBean对象可以感知自己被绑定到 Session中和从Session中删除的事件
当对象被绑定到 HttpSession 对象中时,web 服务器调用该对象的  void valueBound(HttpSessionBindingEvent event) 方法
当对象从 HttpSession 对象中解除绑定时,web 服务器调用该对象的 void valueUnbound(HttpSessionBindingEvent event)方法
*/


public class JavaBeanListener implements HttpSessionBindingListener {
String name;
public JavaBeanListener(){};

public JavaBeanListener(String name){
    this.name = name;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

@Override
public void valueBound(HttpSessionBindingEvent event) {
    System.out.println(name+"被加入到session中");
}

@Override
public void valueUnbound(HttpSessionBindingEvent event) {
    System.out.println(name+"被踢出session中");
    }
}


<body>
<%
    JavaBeanListener jbl = new JavaBeanListener("张三");
    session.setAttribute("jbl",jbl);
    session.removeAttribute("jbl");
%>
</body>

 

程序运行结果

yyFElR.jpg

session的钝化和活化

钝化和活化实质上就是序列化和反序列化,想要实现钝化和活化需要实现HttpSessionActivationListener接口,并配置context.xml文件。

当绑定到HttpSession对象中的javabean对象将要随HttpSession对象被钝化(序列化)之前,web服务器调用该javabean对象的void sessionWillPassivate(HttpSessionEvent event) 方法。这样javabean对象就可以知道自己将要和HttpSession对象一起被序列化(钝化)到硬盘中.   

当绑定到HttpSession对象中的javabean对象将要随HttpSession对象被活化(反序列化)之后,web服务器调用该javabean对象的void sessionDidActive(HttpSessionEvent event)方法。这样javabean对象就可以知道自己将要和 HttpSession对象一起被反序列化(活化)回到内存中。

程序范例

public class JavaBeanListener2 implements HttpSessionActivationListener , Serializable {


    private int id;
    private String name;
    public JavaBeanListener2(){};
    public JavaBeanListener2(int id,String name){
    this.id = id;
    this.name = name;
    }

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}
//监听在钝化之前
@Override
public void sessionDidActivate(HttpSessionEvent se) {
    System.out.println("JavaBeanListener2从硬盘中活化,Session的id是"+se.getSession().getId());

}
//监听在活化之后
@Override
public void sessionWillPassivate(HttpSessionEvent se) {
    System.out.println("JavaBeanListener2被钝化到硬盘中"+se.getSession().getId());

    }
}

 

context.xml文件的内容如下:

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

在context.xml文件文件中配置了1分钟之后就将HttpSession对象钝化到本地硬盘的一个listener文件夹中

 

jsp测试代码:

<body>

<%
    JavaBeanListener2 jbl2 = new JavaBeanListener2();
    jbl2.setId(10);
    jbl2.setName("张三");
    session.setAttribute("jbl2",jbl2);
    session.removeAttribute("jbl2");
%>

</body>

 

访问这个jsp页面,服务器就会马上创建一个HttpSession对象,然后将实现了HttpSessionActivationListener接口的JavaBean对象绑定到session对象中,这个jsp页面在等待1分钟之后没有人再次访问,那么服务器就会自动将这个HttpSession对象钝化(序列化)到硬盘上。

程序运行结果

yyEp0P.jpg

从硬盘中活化

<html>
<head>
    <title>活化Session中的对象并取值</title>
    </head>
    <body>
        ID:${sessionScope.jbl2.id}<br>
        name:${sessionScope.jbl2.name}<br>
    </body>
</html>

 

测试页面

yyEPk8.jpg

posted @ 2021-02-14 15:51  aishimin  阅读(148)  评论(0)    收藏  举报