監聽域物件建立和銷燬的Listener
1.什麼是Servlet監聽器?
先來看看什麼是監聽器。監聽器是專門用於對其它物件身上發生的事件或狀態改變進行監聽和相應處理的物件,當被監視的物件發生情況時立即採取相應的行動。Servlet監聽器是Servlet規範中定義的一種特殊類,它用於監聽web應用程式的ServletContext,HttpSession和ServletRequest等域物件的建立與銷燬事件,以及監聽這些域物件中的屬性發生修改的事件。
按監聽的事件型別Servlet監聽器可分為如下三種類型:
- 監聽域物件自身的建立和銷燬的事件監聽器
- 監聽域物件中的屬性的增加和刪除的事件監聽器
- 監聽繫結到HtppSession域中的某個物件的狀態的事件監聽器
2.域物件建立和銷燬的事件監聽器
域物件建立和銷燬的事件監聽器就是用來監聽ServletContext,HttpSession,HttpServletRequest這三個物件的建立和銷燬事件的監聽器。域物件的建立和銷燬時機:
- ServletContext:當web伺服器啟動時為每個web應用程式建立相應的ServletContext物件,web伺服器關閉時為每個web應用程式銷燬相應的ServletContext物件。
- HttpSession:瀏覽器開始與伺服器會話時建立,呼叫HttpSession.invalidate();超過了session的最大有效時間間隔;伺服器程序被停止。
- ServletRequest:每次請求開始時建立,每次訪問結束後銷燬。
3.如何編寫Servlet監聽器?
- Servlet規範為每種事件監聽器都定義了相應的介面,編寫事件監聽程式只需要實現這些介面。
- 在web.xml中進行註冊,web伺服器按照它們在web.xml中的註冊順序來載入和執行這些Servlet事件監聽器。
4.ServletContextListener介面
ServletContextListener介面用於監聽ServletContext物件的建立和銷燬事件。建立一個Session時,激發sessionCreated(HttpSessionEvent se)方法,銷燬一個Session時,激發sessionDestroyed(HttpSessionEvent se)方法。
編寫監聽器,程式碼如下:
package com.javaweb.Listener; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class servletContextListenerTest implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { System.out.println("ServletContext物件被建立"); } @Override public void contextDestroyed(ServletContextEvent sce) { System.out.println("ServletContext物件被銷燬"); } }
在web.xml中進行配置:
<listener> <description>ServletContextListener</description> <listener-class>com.javaweb.Listener.servletContextListenerTest</listener-class> </listener>
ServletContextListener是最常用的Listener,可以在當前web應用被載入時對當前web應用的相關資源進行初始化操作;建立資料庫連線池,建立Spring的IOC容器,讀取當前web應用的初始化引數。
5.通過Listener理解域物件生命週期
5.1 request:是一個請求,當一個響應返回時,即被銷燬,當傳送一個請求時被建立。
index.jsp
<body> <a href="Listener/test.jsp">to test page</a> <% request.setAttribute("resquestKey","requestValue"); %> </body>
test.jsp
<body> <%= request.getAttribute("resquestKey") %> </body>
執行index.jsp,傳送一個請求,返回一個響應頁面,
request請求被銷燬。此時在index.jsp頁面設定的屬性request.setAttribute("resquestKey","requestValue");在test.jsp頁面中獲取不到對應的屬性值,入下:
可以通過請求轉發(請求轉發只有一個request)實現上述功能:
<% request.setAttribute("resquestKey","requestValue"); %> <jsp:forward page="/Listener/test.jsp"></jsp:forward>
在index.jsp頁面點選超連結到TestServlet,在TestServlet中將請求轉發到test.jsp頁面。中間涉及到的是一個request請求。
index.jsp
<body> <a href="TestServlet">testServlet</a> </body>
testServlet.java
package com.javaweb.Listener; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class testServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setAttribute("requestKey", "requestValue2"); request.getRequestDispatcher("/Listener/test.jsp").forward(request, response); } }
test.jsp
<body> <%= request.getAttribute("requestKey") %> </body>
web.xml中進行配置:
<servlet> <servlet-name>testServlet</servlet-name> <servlet-class>com.javaweb.Listener.testServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>testServlet</servlet-name> <url-pattern>/TestServlet</url-pattern> </servlet-mapping>
執行後可以獲得設定的request屬性值。
若將testServlet.java中的請求轉發request.getRequestDispatcher("/Listener/test.jsp").forward(request, response);改為請求重定向response.sendRedirect("/Listener/test.jsp");則涉及到兩個request請求。
5.2 session:當第一次訪問web應用的一個JSP或Servlet時,且該JSP或servelet中還需要建立session物件,此時伺服器會建立一個session物件。
session銷燬:session過期;直接呼叫session的invalidate方法;當前web應用被解除安裝。
session過期:
<% HttpSession session=request.getSession(true); session.setMaxInactiveInterval(10); %>
session的invalidate方法:
<% HttpSession session=request.getSession(true); session.invalidate(); %>
關閉瀏覽器,並不意味著session被銷燬,還可以通過sessionid找到伺服器中的session物件。
5.3 application:貫穿於當前的web應用的生命週期,當前web應用被載入時建立application物件,當前web應用被解除安裝時銷燬application物件。