007_监听器
一. 監聽器
1. 監聽某一個事件的發生, 狀態的改變。
2. 監聽器的內部機制: 其實就是接口回調。
3. Servlet一共有8個監聽器。按作用分為三大類: 監聽三個作用域的創建和銷毀、監聽三個作用域屬性狀態的變更和監聽httpSession里面存值狀態的變更。
4. 被監聽的三個作用域分別是: request(HttpServletRequest)、session(HttpSession)和application(ServletContext)。
二. 監聽三個作用域的創建和銷毀
1. ServletContextListener監控ServletContext的創建和銷毀。
1.1. 項目被服務器(Tomcat服務器)加載的時候創建ServletContext; 項目被服務器(Tomcat服務器)移除或關閉服務器的時候銷毀ServletContext。
1.2. 創建名為ServletContextListener的Web工程
1.3. 編寫MyServletContextListener.java實現ServletContextListener接口
package com.lywgames.listener;import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener;public class MyServletContextListener implements ServletContextListener {/*** 項目被服務器(Tomcat服務器)加載的時候調用*/@Overridepublic void contextInitialized(ServletContextEvent sce) {System.out.println("servletcontext創建");}/*** 項目被服務器(Tomcat服務器)移除的時候調用*/@Overridepublic void contextDestroyed(ServletContextEvent sce) {System.out.println("servletcontext銷毀");} }1.4. 在web.xml里配置監聽器
1.5. 運行該項目, 監控到servletcontext被創建了
1.6. 關閉服務器, 監控到servletcontext被銷毀了
2. ServletRequestListener監控request的創建和銷毀。
2.1. 客戶端(瀏覽器)訪問服務器上的資源的時候就會有request的創建; 服務器對客戶端做出響應的時候就會有request的銷毀。
2.2. 客戶端(瀏覽器)訪問服務器上的任何資源都會有request的創建, 包括html、jsp和servlet。
2.3. 創建名為ServletRequestListener的Web工程
2.4. 編寫MyServletContextListener.java實現ServletRequestListener接口
package com.lywgames.listener;import javax.servlet.ServletRequestEvent; import javax.servlet.ServletRequestListener;public class MyServletRequestListener implements ServletRequestListener {/*** 有客戶端訪問服務器資源的時候調用*/@Overridepublic void requestInitialized(ServletRequestEvent sre) {System.out.println("有request請求");}/*** 服務器對客戶端做出響應的時候調用*/@Overridepublic void requestDestroyed(ServletRequestEvent sre) {System.out.println("有request銷毀了");} }2.6. 創建一個MyServlet.java類
package com.lywgames.listener;import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;public class MyServlet extends HttpServlet {private static final long serialVersionUID = 1L;@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("text/html;charset=utf-8");resp.getWriter().print("請求Servlet成功。");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);} }2.7. 創建index.html
<!DOCTYPE html> <html><head><meta charset="UTF-8" /><title>訪問html有request請求</title></head><body><h1>index.html</h1></body> </html>2.8. 創建index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html> <html><head><meta charset="UTF-8" /><title>訪問jsp有request請求</title></head><body><h1>index.jsp</h1></body> </html>2.9. 在web.xml里配置監聽器和Servlet
2.10. 部署項目, 訪問index.html、index.jsp和MyServlet都有request的創建和銷毀
3. HttpSessionListener監控session的創建和銷毀。
3.1. 只要有getSession()方法的調用, 就會有session的創建。訪問jsp的時候, 因為jsp頁面有session=true(默認也是true)的設置, 所以訪問jsp就會有session的創建; 如果設置session=false, 就不會有session的創建。訪問Servlet的時候, 如果Servlet里有getSession()的調用, 則會創建session; 如果沒有getSession()的調用, 則不會創建session。訪問html沒有session的創建。超過30分鐘或者非正常關閉服務器, 則會銷毀session; 正常關閉服務器會序列化session。
3.2. 創建名為HttpSessionListener的Web工程
3.3. 編寫MyHttpSessionListener.java實現HttpSessionListener接口
package com.lywgames.listener;import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener;public class MyHttpSessionListener implements HttpSessionListener {@Overridepublic void sessionCreated(HttpSessionEvent hse) {System.out.println("創建了session");}@Overridepublic void sessionDestroyed(HttpSessionEvent hse) {System.out.println("銷毀了session");} }3.4. 創建MyServlet并調用getSession()方法(如果不調用getSession(), 方法不會創建session)
package com.lywgames.listener;import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;public class MyServlet extends HttpServlet {private static final long serialVersionUID = 1L;@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 調用getSession()方法req.getSession();resp.setContentType("text/html;charset=utf-8");resp.getWriter().print("請求Servlet成功。");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);} }3.5. 創建index.jsp(如果設置session=false, 不會創建session)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" session="true"%><!DOCTYPE html> <html><head><meta charset="UTF-8" /><title>訪問jsp有session創建</title></head><body><h1>index.jsp</h1></body> </html>3.6. 創建index.html(請求html不會創建session)
<!DOCTYPE html> <html><head><meta charset="UTF-8" /><title>訪問html沒有session創建</title></head><body><h1>index.html</h1></body> </html>3.7. 在web.xml里配置監聽器和Servlet
3.8. 部署項目, 訪問index.jsp和MyServlet都有session的創建(而且一次會話只會創建一個session)
4. ServletContextListener的作用
4.1. 在servletcontext創建的時候, 完成自己想要的初始化工作。
5. HttpSessionListener可以用來統計在線訪問次數。
三. 監聽三個作用域中值的添加、替換和移除
1. ServletContextAttributeListener監聽servletContext作用域中值的添加、替換和移除。
1.1. 創建名為ServletContextAttributeListener的Web工程
1.2. 創建MyServletContextAttributeListener.java
package com.lywgames.listener;import javax.servlet.ServletContextAttributeEvent; import javax.servlet.ServletContextAttributeListener;public class MyServletContextAttributeListener implements ServletContextAttributeListener {@Overridepublic void attributeAdded(ServletContextAttributeEvent sae) {System.out.println("servletContext屬性被添加進來了");}@Overridepublic void attributeRemoved(ServletContextAttributeEvent sae) {System.out.println("servletContext屬性被移除了");}@Overridepublic void attributeReplaced(ServletContextAttributeEvent sae) {System.out.println("servletContext屬性被替換了");}}1.3. 新建index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html> <html><head><meta charset="UTF-8" /><title>servletContext值的添加,替換和移除</title></head><body><%application.setAttribute("name", "lisi");application.setAttribute("name", "zhangsan");application.removeAttribute("name");%> </body> </html>1.4. 在web.xml里配置監聽器
1.5. 訪問index.jsp
2. ServletRequestAttributeListener監聽request作用域中值的添加、替換和移除。
2.1. 創建名為ServletRequestAttributeListener的Web工程
2.2. 創建MyServletRequestAttributeListener.java
package com.lywgames.listener;import javax.servlet.ServletRequestAttributeEvent; import javax.servlet.ServletRequestAttributeListener;public class MyServletRequestAttributeListener implements ServletRequestAttributeListener {@Overridepublic void attributeAdded(ServletRequestAttributeEvent hsbe) {System.out.println("request屬性被添加進來了");}@Overridepublic void attributeRemoved(ServletRequestAttributeEvent hsbe) {System.out.println("request屬性被移除了");}@Overridepublic void attributeReplaced(ServletRequestAttributeEvent hsbe) {System.out.println("request屬性被替換了");}}2.3. 新建index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html> <html><head><meta charset="UTF-8" /><title>request值的添加,替換和移除</title></head><body><%request.setAttribute("name", "lisi");request.setAttribute("name", "zhangsan");request.removeAttribute("name");%></body> </html>2.4. 在web.xml里配置監聽器
2.5. 訪問index.jsp
3. HttpSessionAttributeListener監聽session作用域中值的添加、替換和移除。
3.1. 創建名為HttpSessionAttributeListener的Web工程
3.2. 創建MyHttpSessionAttributeListener.java
package com.lywgames.listener;import javax.servlet.http.HttpSessionAttributeListener; import javax.servlet.http.HttpSessionBindingEvent;public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener {@Overridepublic void attributeAdded(HttpSessionBindingEvent hsbe) {System.out.println("Session屬性被添加進來了");}@Overridepublic void attributeRemoved(HttpSessionBindingEvent hsbe) {System.out.println("Session屬性被移除了");}@Overridepublic void attributeReplaced(HttpSessionBindingEvent hsbe) {System.out.println("Session屬性被替換了");}}3.3. 新建index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html> <html><head><meta charset="UTF-8" /><title>session值的添加,替換和移除</title></head><body><%session.setAttribute("name", "aobama");session.setAttribute("name", "zhangsan");session.removeAttribute("name");%></body> </html>3.4. 在web.xml里配置監聽器
3.5. 訪問index.jsp
四. 監聽httpSession里面存值狀態的變更(這種監聽器不用我們注冊)
1. HttpSessionBindingListener監聽對象與session綁定和解除綁定的動作。
1.1. 創建名為HttpSessionBindingListener的Web工程
1.2. 創建HttpSessionBindingListenerBean.java
package com.lywgames.listener;import javax.servlet.http.HttpSessionBindingEvent; import javax.servlet.http.HttpSessionBindingListener;public class HttpSessionBindingListenerBean implements HttpSessionBindingListener {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic void valueBound(HttpSessionBindingEvent hsbe) {System.out.println("對象被綁定進來了");}@Overridepublic void valueUnbound(HttpSessionBindingEvent hsbe) {System.out.println("對象被解除綁定");}}1.3. 新建一個index.jsp
<%@ page import="com.lywgames.listener.HttpSessionBindingListenerBean"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html> <html><head><meta charset="UTF-8" /><title>監聽對象與session綁定和解除綁定的動作</title></head><body><%HttpSessionBindingListenerBean bean = new HttpSessionBindingListenerBean();bean.setName("lisisi");session.setAttribute("bean", bean);session.removeAttribute("bean");%></body> </html>1.4. 訪問index.jsp
2. HttpSessionActivationListener用于監聽現在session的值是鈍化(序列化)還是活化(反序列化)的動作。
2.1. 鈍化(序列化): 把內存中的數據, 存儲到硬盤上。
2.2. 活化(反序列化): 把硬盤中的數據讀取到內存中。
2.3. session中的值可能會很多, 并且我們有很長一段時間不使用這個內存中的值, 那么可以考慮把session的值可以存儲到硬盤上[鈍化], 等下一次在使用的時候, 在從硬盤上提取出來[活化]。
2.4. 配置session的鈍化時間
2.4.1. 在tomcat里面 conf/context.xml 里面配置: 對所有的運行在這個服務器的項目生效。?
2.4.2. 在conf/Catalina/localhost/context.xml 配置: 對localhost生效。 ?
2.4.3. 在自己的web工程項目中的 META-INF/context.xml: 只對當前的工程生效。
2.4.4. maxIdleSwap: 鈍化時間(以分鐘為單位), directory: 鈍化路徑。
2.5. 創建名為HttpSessionActivationListener的Web工程
2.6. 創建HttpSessionActivationListenerBean.java
package com.lywgames.listener;import java.io.Serializable; import javax.servlet.http.HttpSessionActivationListener; import javax.servlet.http.HttpSessionEvent;public class HttpSessionActivationListenerBean implements HttpSessionActivationListener, Serializable {private static final long serialVersionUID = 1L;private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic void sessionDidActivate(HttpSessionEvent hse) {System.out.println("session中的值被活化了...");}@Overridepublic void sessionWillPassivate(HttpSessionEvent hse) {System.out.println("session中的值被鈍化了...");}}2.7. 新建一個index.jsp
<%@page import="com.lywgames.listener.HttpSessionActivationListenerBean"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html> <html><head><meta charset="UTF-8" /><title>session值的鈍化/活化</title></head><body><%HttpSessionActivationListenerBean bean = new HttpSessionActivationListenerBean();bean.setName("lisisi");session.setAttribute("bean", bean);%><h1>index.jsp</h1></body> </html>2.8. 新建一個list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html> <html><head><meta charset="UTF-8" /><title>session值的鈍化/活化</title></head><body>${bean.name}</body> </html>2.9. 在META-INF目錄下新建一個context.xml
2.10. 訪問index.jsp
2.11. 等待一分鐘后, session中存入的對象鈍化了。同時進入D:\software\eclipse\applicationTomcat70\Tomcat 7.0\work\Catalina\localhost\HttpSessionActivationListener\lywgames目錄下查看:
2.12. 訪問list.jsp, 得到活化后的session數據
總結