[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)
```