## web 加載順序
web.xml的加載順序是:Context-Param -> Listener -> Filter -> Servlet,而同個類型之間的實際程序調用的時候的順序是根據對應的Mapping的順序進行調用。
## Java 監聽器
監聽器用于監聽web應用中某些對象、信息的創建、銷毀、增加,修改,刪除等動作的發生,然后作出相應的響應處理。Listener接口分類:
- ServletContext監聽器
- HttpSession監聽器
- ServletRequest監聽器
## ServletContext 監聽器
**ServletContextListener:**監聽ServletContext對象
```java
package com.listener;
import javax.servlet.ServletRequestEvent;
public class ServletRequestListener implements javax.servlet.ServletRequestListener {
/**
* 該請求即將超出Web應用程序的范圍。
* request將要銷毀
*/
@Override
public void requestDestroyed(ServletRequestEvent event) {
System.out.println("request將要銷毀");
}
/**
* 該請求即將進入Web應用程序的范圍。
* request初始化
*/
@Override
public void requestInitialized(ServletRequestEvent event) {
System.out.println("request初始化");
}
}
```
```html
<!-- ServletContext對象監聽器 -->
<listener>
<listener-class>com.listener.ServletRequestListener</listener-class>
</listener>
```
**ServletContextAttributeListener:**監聽對ServletContext屬性的操作,比如增加、刪除、修改
```java
package com.listener;
import javax.servlet.ServletRequestAttributeEvent;
public class ServletRequestAttributeListener implements javax.servlet.ServletRequestAttributeListener {
/**
* 通知一個新的屬性被添加到servlet請求。 在添加屬性后調用。
*/
@Override
public void attributeAdded(ServletRequestAttributeEvent event) {
System.out.println("request添加屬性后調用");
}
/**
* 通知現有的屬性已經從servlet請求中刪除。 在屬性被刪除后調用。
*/
@Override
public void attributeRemoved(ServletRequestAttributeEvent event) {
System.out.println("request刪除屬性后調用");
}
/**
* 通知servlet請求中已經替換了一個屬性。 在屬性被替換后調用。
*/
@Override
public void attributeReplaced(ServletRequestAttributeEvent event) {
System.out.println("request替換屬性后調用");
String name = event.getName();
Object value = event.getValue();
System.out.println("request被替換的key:" + name + " ,替換前的value:" + value);
}
}
```
```html
<!-- ServletContext屬性的操作監聽器 -->
<listener>
<listener-class>com.listener.ServletRequestAttributeListener</listener-class>
</listener>
```
## HttpSession 監聽器
**HttpSessionListener:**監聽Session對象
```java
package com.listener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
public class HttpSessionListener implements javax.servlet.http.HttpSessionListener {
/**
* 通知會話已創建。
* session創建之后調用
*/
@Override
public void sessionCreated(HttpSessionEvent event) {
System.out.println("session創建之后");
HttpSession session = event.getSession();
}
/**
* 通知會話即將失效。
* session銷毀之前調用
*/
@Override
public void sessionDestroyed(HttpSessionEvent event) {
System.out.println("session銷毀之前");
HttpSession session = event.getSession();
}
}
```
```html
<!-- HttpSession對象監聽器 -->
<listener>
<listener-class>com.listener.HttpSessionListener</listener-class>
</listener>
```
**HttpSessionAttributeListener:**監聽Session中的屬性操作
```java
package com.listener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingEvent;
public class HttpSessionAttributeListener implements javax.servlet.http.HttpSessionAttributeListener {
/**
* 通知某個屬性已被添加到會話中。 在添加屬性后調用。
*/
@Override
public void attributeAdded(HttpSessionBindingEvent event) {
System.out.println("session添加屬性后調用");
HttpSession session = event.getSession();
String name = event.getName();
Object value = event.getValue();
System.out.println("被添加到session中的屬性:" + "key=" + name + " ,value=" + value);
}
/**
* 通知某個屬性已從會話中刪除。 在屬性被刪除后調用。
*/
@Override
public void attributeRemoved(HttpSessionBindingEvent event) {
System.out.println("session刪除屬性后調用");
HttpSession session = event.getSession();
String name = event.getName();
Object value = event.getValue();
System.out.println("被刪除的session中的屬性:" + "key=" + name + " ,value=" + value);
}
/**
* 在會話中通知屬性已被替換。 在屬性被替換后調用。
*/
@Override
public void attributeReplaced(HttpSessionBindingEvent event) {
System.out.println("session替換屬性后調用");
HttpSession session = event.getSession();
String name = event.getName();
Object value = event.getValue();
System.out.println("被替換的session中的屬性:" + "key=" + name + " ,替換之前的value=" + value);
}
}
```
```html
<!-- HttpSession屬性的操作監聽器 -->
<listener>
<listener-class>com.listener.HttpSessionAttributeListener</listener-class>
</listener>
```
**HttpSessionBindingListener監聽器:**感知Session綁定的事件監聽器
```java
package com.listener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingEvent;
public class HttpSessionBindingListener implements javax.servlet.http.HttpSessionBindingListener {
/**
* 通知對象它正在被綁定到會話并標識會話。(還未綁定)
*/
@Override
public void valueBound(HttpSessionBindingEvent event) {
System.out.println("當前對象正在綁定到session中,還未綁定");
HttpSession session = event.getSession();
String name = event.getName();
Object value = event.getValue();
System.out.println("將要被綁定到session中的key值:" + name + "value值:" + value);
System.out.println("value值是否是當前對象:" + (value == this));//true
Object valueNow = session.getAttribute(name);
System.out.println("valueNow:" + valueNow);//null,還未綁定
}
/**
* 通知對象它正在從會話中解除綁定并標識會話。(還未解除綁定)
*/
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
System.out.println("當前對象它正在從會話中解除綁定");
HttpSession session = event.getSession();
String name = event.getName();
Object value = event.getValue();
System.out.println("將要解除綁定session中的key值:" + name + "value值:" + value);
System.out.println("value值是否是當前對象:" + (value == this));//true
Object valueNow = session.getAttribute(name);
System.out.println("valueNow:" + valueNow);//null,還未解除綁定
}
}
```
**測試頁面**
```html
<%@page import="cn.itcast.erp.listener.session.HttpSessionBindingListener"%>
<%@page import="cn.itcast.erp.listener.session.HttpSessionActivationListener"%>
<%@page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>測試HttpSessionActivationListener監聽(session的活化和鈍化)</title>
</head>
<body>
<%
//測試session活化和鈍化監聽器HttpSessionActivationListener
session.setAttribute("sessionActivation",new HttpSessionActivationListener1());
//測試session綁定和解綁監聽器
session.setAttribute("sessionBind", new HttpSessionBindingListener1());
session.removeAttribute("sessionBind");
%>
<h1>session活化和鈍化監聽</h1>
</body>
</html>
```
**HttpSessionActivationListener:**監聽HTTP會話的active和passivate情況,passivate是指非活動的session被寫入持久設備(比如硬盤),active相反。注意:HttpSessionActivationListener不需要web.xml配置文件。
## ServletRequest 監聽器
**ServletRequestListener:**監聽Request對象
```java
package com.listener;
import javax.servlet.ServletRequestEvent;
public class ServletRequestListener implements javax.servlet.ServletRequestListener {
/**
* 該請求即將超出Web應用程序的范圍。
* request將要銷毀
*/
@Override
public void requestDestroyed(ServletRequestEvent event) {
System.out.println("request將要銷毀");
}
/**
* 該請求即將進入Web應用程序的范圍。
* request初始化
*/
@Override
public void requestInitialized(ServletRequestEvent event) {
System.out.println("request初始化");
}
}
```
```xml
<!-- ServletRequest對象監聽器 -->
<listener>
<listener-class>com.listener.ServletRequestListener</listener-class>
</listener>
```
**ServletRequestAttributeListener:**監聽Requset中的屬性操作
```java
package com.listener;
import javax.servlet.ServletRequestAttributeEvent;
public class ServletRequestAttributeListener implements javax.servlet.ServletRequestAttributeListener {
/**
* 通知一個新的屬性被添加到servlet請求。 在添加屬性后調用。
*/
@Override
public void attributeAdded(ServletRequestAttributeEvent event) {
System.out.println("request添加屬性后調用");
}
/**
* 通知現有的屬性已經從servlet請求中刪除。 在屬性被刪除后調用。
*/
@Override
public void attributeRemoved(ServletRequestAttributeEvent event) {
System.out.println("request刪除屬性后調用");
}
/**
* 通知servlet請求中已經替換了一個屬性。 在屬性被替換后調用。
*/
@Override
public void attributeReplaced(ServletRequestAttributeEvent event) {
System.out.println("request替換屬性后調用");
String name = event.getName();
Object value = event.getValue();
System.out.println("request被替換的key:" + name + " ,替換前的value:" + value);
}
}
```
```xml
<!-- ServletRequest屬性的操作監聽器 -->
<listener>
<listener-class>com.listener.ServletRequestAttributeListener</listener-class>
</listener>
```