文章目錄
1 監聽器簡介
在Java中與監聽器相關的:AWT、SAX(基於事件驅動)。
Listener接口:
(1)它是一個接口,內容由我們來實現;
(2)它需要註冊,例如註冊在按鈕上;
(3)監聽器中的方法,會在特殊事件發生時被調用。
觀察者:
(1)事件源;
|——小偷
(2)事件;
|——偷東西
(3)監聽器;
|——警察
|——監聽器中的方法:抓捕
2 監聽器概述以及生命週期監聽
在JavaWeb被監聽的事件源爲ServletContext、HttpSession、ServletRequest,即三大域對象。
(1)監聽域對象“創建”與“銷燬”的監聽器;
(2)監聽域對象“操作域屬性”的監聽器;
(3)監聽HttpSession的監聽器。
ServletContextListener:服務器啓動時創建,服務器關閉時銷燬。
(1)生死監聽:public interface ServletContextListener extends java.util.EventListener
|——方法:default void contextInitialized(ServletContextEvent sce)
,創建ServletContext時調用;
|——方法:default void contextDestroyed(ServletContextEvent sce)
,銷燬ServletContext時調用。
(2)屬性監聽:public interface ServletContextAttributeListener extends java.util.EventListener
|——方法:default void attributeAdded(ServletContextAttributeEvent scae)
:添加屬性時調用;
|——方法:default void attributeReplaced(ServletContextAttributeEvent scae)
:替換屬性時調用;
|——方法:default void attributeRemoved(ServletContextAttributeEvent scae)
:移除屬性時調用。
HttpSessionListener:
(1)生死監聽:public interface HttpSessionListener extends java.util.EventListener
|——方法:default void sessionCreated(HttpSessionEvent se)
:創建Session調用;
|——方法:default void sessionDestroyed(HttpSessionEvent se)
,Session銷燬時調用。
(2)屬性監聽:public interface HttpSessionAttributeListener extends java.util.EventListener
|——方法:default void attributeAdded(HttpSessionBindingEvent se)
:添加屬性時調用;
|——方法:default void attributeReplaced(HttpSessionBindingEvent se)
:替換屬性時調用;
|——方法:default void attributeRemoved(HttpSessionBindingEvent se)
:移除屬性時調用。
ServletRequestListener:發出請求就創建一遍
(1)生死監聽:public interface ServletRequestListener extends java.util.EventListener
|——方法:default void requestInitialized(ServletRequestEvent sre)
,出生時調用;
|——方法:default void requestDestroyed(ServletRequestEvent sre)
,死亡時調用。
(2)屬性監聽:public interface ServletRequestAttributeListener extends java.util.EventListener
|——方法:default void attributeAdded(ServletRequestAttributeEvent srae)
:添加屬性時調用;
|——方法:default void attributeReplaced(ServletRequestAttributeEvent srae)
:替換屬性時調用;
|——方法:default void attributeRemoved(ServletRequestAttributeEvent srae)
:移除屬性時調用。
javaWeb中完成編寫監聽器:
(1)寫一個監聽器類:要求必須去實現某個監聽器接口;
package org.lks.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
/**
* Application Lifecycle Listener implementation class AListener
*
*/
@WebListener
public class AListener implements ServletContextListener {
/**
* @see ServletContextListener#contextDestroyed(ServletContextEvent)
*/
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("destory!");
}
/**
* @see ServletContextListener#contextInitialized(ServletContextEvent)
*/
public void contextInitialized(ServletContextEvent sce) {
System.out.println("init!");
}
}
(2)註冊,是在web.xml中配置完成註冊,配置代碼如下:
<listener>
<listener-class></listener-class>
</listener>
可以在ServletContextListener這個監聽器中放一些在Tomcat啓動時就要完成的代碼。
事件對象:
(1)ServletContextEvent:public class ServletContextEvent extends java.util.EventObject
|——方法:public ServletContext getServletContext()
:獲取ServletContext實例化對象。
(2)ServletContextAttributeEvent:public class ServletContextAttributeEvent extends ServletContextEvent
|——方法:public java.lang.String getName()
:獲取要更改的屬性名。
|——方法:public java.lang.Object getValue()
:獲取屬性值,如果是添加操作,則返回添加的屬性值,如果時刪除操作,則返回刪除前的屬性值,如果是修改操作,則返回修改前的屬性值。
(3)HttpSessionEvent:public class HttpSessionEvent extends java.util.EventObject
|——方法:public HttpSession getSession()
:獲取session。
(4)HttpSessionBindingEvent:public class HttpSessionBindingEvent extends HttpSessionEvent
|——方法:public HttpSession getSession()
:獲取session;
|——方法:public java.lang.String getName()
:獲取屬性名;
|——方法:public java.lang.Object getValue()
:獲取屬性值。
(5)ServletRequestEvent:public class ServletRequestEvent extends java.util.EventObject
|——方法:public ServletRequest getServletRequest()
:獲取ServletRequest實例化對象。
|——方法:public ServletContext getServletContext()
:獲取ServletContext實例化對象。
(6)ServletRequestAttributeEvent:public class ServletRequestAttributeEvent extends ServletRequestEvent
|——方法:public java.lang.String getName()
:獲取屬性名;
|——方法:public java.lang.Object getValue()
:獲取屬性值。
3 監聽器值屬性監聽器
下面的代碼實現ServletContextAttributeListener接口,實現屬性的監聽:
package org.lks.listener;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.annotation.WebListener;
/**
* Application Lifecycle Listener implementation class AListener
*
*/
@WebListener
public class AListener implements ServletContextAttributeListener {
public void attributeAdded(ServletContextAttributeEvent scae) {
System.out.println( scae.getName() + "attribute added, His value is " + scae.getValue());
}
public void attributeRemoved(ServletContextAttributeEvent scae) {
System.out.println( scae.getName() + "attribute removed, His value is " + scae.getValue());
}
public void attributeReplaced(ServletContextAttributeEvent scae) {
System.out.println( scae.getName() + "attribute replaced, His old value is " + scae.getValue() + "new value is " + scae.getServletContext().getAttribute(scae.getName()));
}
}
4 監聽器之HttpSessionBindingListener
感知監聽(與HttpSession相關)
(1)它用來添加到JavaBean上,而不是添加到三大域上。
(2)不需要再web.xml中註冊
讓對象去實現HttpSessionBindingListener接口,此對象就知道自己是否被添加到Session中去了。
HttpSessionBindingListener:添加到javabean上,javabean就知道自己是否添加到session中了。
package org.lks.listener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
public class User implements HttpSessionBindingListener {
private String name;
private int age;
public User() {
super();
}
public User(String name, int age) {
super();
this.name = name;
this.age = 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 String toString() {
return "User [name=" + name + ", age=" + age + "]";
}
@Override
public void valueBound(HttpSessionBindingEvent event) {
// TODO Auto-generated method stub
System.out.println("bound");
}
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
// TODO Auto-generated method stub
System.out.println("unbound");
}
}
5 session的序列化
設置不允許session序列化:再Tomcat的context.xml文件中加入一下代碼:
<Manager pathname="" />
需要讓類實現Serializable接口,使其可以被序列化。
package org.lks.listener;
import java.io.Serializable;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
public class User implements HttpSessionBindingListener,Serializable {
private String name;
private int age;
public User() {
super();
}
public User(String name, int age) {
super();
this.name = name;
this.age = 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 String toString() {
return "User [name=" + name + ", age=" + age + "]";
}
@Override
public void valueBound(HttpSessionBindingEvent event) {
// TODO Auto-generated method stub
System.out.println("bound");
}
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
// TODO Auto-generated method stub
System.out.println("unbound");
}
}
6 session的鈍化和活化
鈍化session,就是把session通過序列化的方式保存到硬盤文件中。活化session就是把硬盤文件中的session在反序列化回內存中。
注意,因爲鈍化和活化session,其實就是使用序列化和反序列化技術把session從內存保存到硬盤,和把session從硬盤加載到內存。這說明如果Person類沒有實現Serializable,那麼當session鈍化時就不會鈍化Person,而是把Person從session移除再鈍化。這也說明session活化後,session中就不在有Person對象了。
步驟:
(1)先不管HttpSessionActivationListener監聽器接口,先來配置Tomcat鈍化session參數,把下面配置文件放到Tomcat目錄下的conf\catalina\localhost目錄下,文件名爲項目名稱。
<Context>
<!-- -->
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
<Store calssName="org.apache.catalina.session.FileStore" directory="mysession" />
</Manager>
</Context>
7 監聽器之HttpSessionActivationListener
HttpSessionActivationListener:Tomcat會在session從時間不被使用時鈍化session對象,所謂鈍化session,就是把session通過序列化的方式保存到硬盤文件中。當用戶再使用session時,Tomcat還會把鈍化的對象再活化session,所謂的活化就是把硬盤文件中的session在反序列化回內存中。當session被Tomcat鈍化時,session中的存儲對象也被鈍化,當session被活化時,也會把session中存儲的對象活化。如果某個類實現了HttpSessionActivationListener接口後,當對象隨着session被鈍化和活化時,下面兩個方法就會被調用:
(1)default void sessionWillPassivate(HttpSessionEvent se)
:當對象感知被活化時調用此方法;
(2)default void sessionDidActivate(HttpSessionEvent se)
:當對象感知被鈍化時調用此方法。
package org.lks.listener;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionEvent;
public class User implements HttpSessionActivationListener {
private String name;
private int age;
public User() {
super();
}
public User(String name, int age) {
super();
this.name = name;
this.age = 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 String toString() {
return "User [name=" + name + ", age=" + age + "]";
}
@Override
public void sessionWillPassivate(HttpSessionEvent se) {
System.out.println("born");
}
@Override
public void sessionDidActivate(HttpSessionEvent se) {
System.out.println("die");
}
}