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對象的創建和銷毀事件。
編寫監聽器,代碼如下:
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應用的初始化參數。
監聽域對象創建和銷毀的Listener還有HttpSessionListener以及ServletRequestListener。用法類似ServletContextListener。
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對象。
wx搜索“程序員考拉”,專注java領域,一個伴你成長的公眾號!