[TOC]
# 1. 监听Context对象的创建和销毁
步骤如下:
**1. 实现接口ServletContextListener**
```java
public class CustomServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
//可以获取ServletContext -> sce.getServletContext()
System.out.println(this.getClass().getSimpleName() + "->应用启动了");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println(this.getClass().getSimpleName() + "->应用关闭了");
}
}
```
**2. `web.xml`中启用监听器**
```xml
<listener>
<listener-class>com.learn.servlet02.listener.CustomServletContextListener</listener-class>
</listener>
```
**3. 演示**
启动项目,然后再关闭项目,控制打印结果如下。
```java
CustomServletContextListener->应用启动了
CustomServletContextListener->应用关闭了
```
<br/>
# 2. 监听Request对象属性的变化
步骤如下:
**1. 编写一个Servlet类方便用来演示**
```java
@WebServlet("/listener")
public class ListenerServlet extends BaseServlet {
public void listener01(HttpServletRequest request, HttpServletResponse response) {
//添加属性
request.setAttribute("username", "zhangsan");
//替换属性
request.setAttribute("username", "lisi");
//移除属性
request.removeAttribute("username");
}
}
```
**2. 实现接口ServletRequestAttributeListener**
```java
public class CustomServletRequestAttributeListener implements ServletRequestAttributeListener {
@Override
public void attributeAdded(ServletRequestAttributeEvent srae) {
//可以获取ServletContext -> srae.getServletContext()
//可以获取ServletRequest -> srae.getServletRequest()
System.out.println(this.getClass().getSimpleName() + "->添加属性了");
System.out.println(srae.getServletRequest().getAttribute("username"));
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent srae) {
System.out.println(this.getClass().getSimpleName() + "->移除属性了");
System.out.println(srae.getServletRequest().getAttribute("username"));
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent srae) {
System.out.println(this.getClass().getSimpleName() + "->替换属性了");
System.out.println(srae.getServletRequest().getAttribute("username"));
}
}
```
**3. `web.xml`中启用监听器**
```xml
<listener>
<listener-class>com.learn.servlet02.listener.CustomServletRequestAttributeListener</listener-class>
</listener>
```
**4. 访问Servlet,控制台打印结果如下**
```
CustomServletRequestAttributeListener->添加属性了
zhangsan
CustomServletRequestAttributeListener->替换属性了
lisi
CustomServletRequestAttributeListener->移除属性了
null
```
<br/>
# 3. 监听实体类是否在session中
步骤如下:
**1. 编写一个Servlet方便用来演示**
```java
@WebServlet("/listener")
public class ListenerServlet extends BaseServlet {
public void listener03(HttpServletRequest request, HttpServletResponse response) {
HttpSession session = request.getSession();
//将Student添加到session中
session.setAttribute("student", Student.builder().id(1).name("zhangsan").age(25).build());
//session.removeAttribute("student");
}
}
```
**2. 实体类实现接口**
```java
@Data
@Builder
public class Student implements HttpSessionBindingListener {
private Integer id;
private String name;
private Integer age;
/**
* 当Student被session.setAttribute("student", Student)时该方法被调用.
*/
@Override
public void valueBound(HttpSessionBindingEvent event) {
//可以获取HttpSession -> event.getSession()
System.out.println(this.getClass().getSimpleName() + "->被添加到session了");
System.out.println(event.getSession().getAttribute("student"));
}
/**
* Student是否被session.removeAttribute("student")时该方法都会被调用.
*/
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
System.out.println(this.getClass().getSimpleName() + "->从session中移除了");
System.out.println(event.getSession().getAttribute("student"));
}
}
```
**3. 访问Servlet,控制台打印结果如下**
```
---- 1. 当不调用session.removeAttribute("student")时控制台打印如下 ----
Student->被添加到session了
Student(id=1, name=zhangsan, age=25)
Student->从session中移除了
Student(id=1, name=zhangsan, age=25)
---- 2. 当调用session.removeAttribute("student")时控制台打印结果如下 ----
Student->被添加到session了
null
Student->从session中移除了
null
```
<br/>
# 4. 监听实体类序列化与反序列化
步骤如下:
**1. 实体类实现接口HttpSessionActivationListener, Serializable**
```java
@Data
@Builder
public class Account implements HttpSessionActivationListener, Serializable {
private Integer id;
private String username;
private String password;
/**
* Account随session序列化时被调用
*/
@Override
public void sessionWillPassivate(HttpSessionEvent se) {
System.out.println(this.getClass().getSimpleName() + "->序列化了");
System.out.println(se.getSession().getAttribute("account"));
}
/**
* Account随session反序列化时被调用
*/
@Override
public void sessionDidActivate(HttpSessionEvent se) {
System.out.println(this.getClass().getSimpleName() + "->反序列化了");
System.out.println(se.getSession().getAttribute("account"));
}
}
```
**2. 编写Servlet方便用来演示**
```java
@WebServlet("/listener")
public class ListenerServlet extends BaseServlet {
public void listener02(HttpServletRequest request, HttpServletResponse response) {
HttpSession session = request.getSession();
//将Account添加到session中
session.setAttribute("account", Account.builder().id(1).username("zhangsan").password("123456").build());
}
}
```
**3. 编写`webapp/META-INF/content.xml`方便用来演示**
```xml
<Context>
<!-- 一分钟后将session序列化到本地磁盘中 -->
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
<Store className="org.apache.catalina.session.FileStore" directory="gacl"/>
</Manager>
</Context>
```
**4. 访问Servlet,然后等待1分钟,再访问Servlet,控制打印结果如下**
```
Account->序列化了
Account(id=1, username=zhangsan, password=123456)
Account->反序列化了
Account(id=1, username=zhangsan, password=123456)
```