## 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>
```