目錄
1.5 ServletContextListener 接口(常用)
1.9 **ServletContextListener接口小結(常用)
1.10 ServletRequestListener接口和HttpSessionListener接口小結
2.1 例1 簡單的ServletContextListener
2.2 例2 簡單的ServletRequestListener和HttpSessionListener
servlet監控器實際使用中相對比較少,可以瞭解一下
一、知識點
1.1 簡介
- 監聽器:專門用於對其他對象身上發生的事件或狀態改變進行監聽和相應處理的對象,當被監視的對象發生情況時,立即採取相應的行動。
- Servlet 監聽器:Servlet 規範中定義的一種特殊類,它用於監聽 web 應用程序中的 ServletContext, HttpSession 和 ServletRequest 等域對象的創建與銷燬事件,以及監聽這些域對象中的屬性發生修改的事件。
1.2 Servlet 監聽器的分類
- 按監聽的事件類型 Servlet 監聽器可分爲如下三種類型:
- 監聽域對象自身的創建和銷燬的事件監聽器
- 監聽域對象中的屬性的增加和刪除的事件監聽器
- 監聽綁定到 HttpSession 域中的某個對象的狀態的事件監聽器
1.3 編寫 Servlet 監聽器
- Servlet 規範爲每種事件監聽器都定義了相應的接口,開發人員編寫的事件監聽器程序只需實現這些接口,web 服務器根據用戶編寫的事件監聽器所實現的接口把它註冊到相應的被監聽對象上
- 一些 Servlet 事件監聽器需要在 web 應用程序的 web.xml 文件中進行註冊,一個 web.xml 文件中可以註冊多個 Servlet 事件監聽器,web 服務器按照它們在 web.xml 文件中的註冊順序來加載和註冊這些 Serlvet 事件監聽器。
- Serlvet 事件監聽器的註冊和調用過程都是由 web 容器自動完成的,當發生被監聽的對象被創建,修改或銷燬事件時,web容器將調用與之相關的 Servlet 事件監聽器對象的相關方法,開發人員在在這些方法中編寫的事件處理代碼即被執行
- 由於一個 web 應用程序只會爲每個事件監聽器創建一個對象,有可能出現多個線程同時調用同一個事件監聽器對象的情況,所以,在編寫事件監聽器類時,應考慮多線程安全的問題
1.4 監聽域對象的創建和銷燬
- 域對象創建和銷燬的事件監聽器就是用來監聽 ServletContext, HttpSession, HttpServletRequest 這三個對象的創建和銷燬事件的監聽器。
- 域對象的創建和銷燬時機
1.5 ServletContextListener 接口(常用)
- ServletContextListener 接口用於監聽 ServletContext 對象的創建和銷燬事件。
- 當 ServletContext 對象被創建時,激發contextInitialized (ServletContextEvent sce)方法
- 當 ServletContext 對象被銷燬時,激發contextDestroyed(ServletContextEvent sce)方法
1.6 HttpSessionListener 接口
- HttpSessionListener 接口用於監聽HttpSession對象的創建和銷燬
- 創建一個Session時,激發sessionCreated (HttpSessionEvent se) 方法
- 銷燬一個Session時,激發sessionDestroyed (HttpSessionEvent se) 方法。
1.7 ServletRequestListener接口
- ServletRequestListener 接口用於監聽ServletRequest 對象的創建和銷燬
- 創建一個ServletRequest 對象時,激發requestInitialized(ServletRequestEvent sre)方法
- 銷燬一個Session時,激發requestDestroyed(ServletRequestEvent sre)方法。
1.8 小結
1.監聽器:專門用於對其他對象身上發生的事件或狀態改變進行監聽和相應處理的對象,當被監視的對象發生情況時,立即採取相應的行動。
2.監聽器的分類:
1).監聽域對象( HttpSssion, request, application )自身的創建和銷燬的事件監聽器
2) .監聽域對象中的屬性的增加和刪除的事件監聽器
3).監聽綁定到HttpSession域中的某個對象的狀態的事件監聽器3.如何編寫監聽器:
1).編寫實現監聽器接口的Java類public class HelloServetContetListner implements ServletContextListener
2).對於第一一種和第二種監聽器需要在web.xml文件中進行註冊:
<listener> <listener-class> com.atguigu.javaweb.test.HelloServletContextListner </listener-class> </listener>
4.監聽域對象( HttpSession, request, application )自身的創建和銷燬的事件監聽器
1). ServletContextListener :最常用的Listener,可以在當前WEB應用被加載時對當前WEB應用的相關資源進行初始化操作:創建數據庫連接池,創建Spring的I0C容器,讀取當前WEB應用的切始化參數..
2). ServletRequestlistener,
3). HttpSessionListener在每個監控器中都有兩個方法:
>在域對象創建後立即被調用的方法:
>在域對象銷燬前被調用的方法:方法的參數:以ServletContextEvent爲例,該對象可以返回ServletContext對象。
5.監聽ServletContext, HttpSession, ServletRequest中添加屬性,替換屬性移除屬性的事件監聽器,(瞭解即可)
1).以ServletRequestAttributeListener爲例://添加屬性時被調用 public void attributeAdded(ServletRequestAttributeEvent srae) { System.out.printn("向request中添加了一個屬性."); //移除屬性時被調用 @Override public void attributeRemoved(ServletRequestAttributeEvent srae) { System.out.printn("從request中移除了-個屬.."): /替換屬性時被調用. @Override public void attributeReplaced(ServletRequestAttributeEvent srae) { System.out.printin(request中屬性替換..);
2).這三個ServletContextAttributeListener,
ServletRequestAtributeListener, HttpSessionAttributeListener監聽器較少被使用.
3). API:
ServletRequestAttributeEvent:
> getName0:獲取屬性的名字
> getValue0: 獲取屬性的值.
6.監聽綁定到HttpSession域中的某個對象的狀態的事件監聽器
1 ). HttpSessionBindingListener (瞭解即可) :
①.監聽實現了該接口的Java類的對象被綁定到session或從session中解除綁定的事件.
//當前對象被綁定到session時調用該方法
public void valueBound(HttpSessionBindingEvent event)
//當前對象從session中解除綁定調用該方法
public void valueUnbound(HttpSessionBindingEvent event)
②.注意:該監聽器不需要在web.xml文件中進行配置.
③. HttpSessionBindingEvent:
getName0
getValue(
getSession02). HttpSessionActivationListener (該監聽器較少被使用) :
①.監聽實現了該接口和Serializable接口(若不實現該接口,則只能寫到磁盤上,但不能讀取出來)的Java類的對象隨session鈍化和活化事件
>活化:從磁盤中讀取session對象
>鈍化:向磁盤中寫入session對象
> session對象存儲在tomcat服務器的work\CatalinaVocalhost\contextPath目錄下. SESSION.SER
②.該監聽器不需要在web.xml文件中進行配置.③.//在活化之後被調用.
public void sessionDidAtiate(HttsessionEvent se)
//在鈍化之前被調用
public void ssiotWlassiatHttpSessionEvent se)
HttpSessionEvent: getSession0
1.9 **ServletContextListener接口小結(常用)
ServletContextListener:
1). what: 監聽ServletContext對象被創建或銷燬的Servlet監聽器2). how:
>創建一個實現了ServletContexltListener的類,並且實現其中的兩個方法
public class HelloServletContextListner implements ServletContextL istener
>在web.xml文件中配置Listener<listener> <listener- class>com.hualinux.javaweb.test.HelloServletContextListner</1istener-class> </listener>
3). why: ServletContextListener 是最常用的Listener,可以在當前WEB應用被加載時對當前WEB應用的相關資源進行初始化操作:
創建數據庫連接池,創建Spring的IOC容器,讀取當前WEB應用的初始化參數...4). API:
// SerlvetContext 對象被創建(即,當前WEB應用被加載時)的時候,Servlet 容器調用該方法。
public void contextInitialized(ServletContextEvent sce)
// SerlvetContext 對象被銷燬之前(即,當前WEB應用被卸載時)的時候,Servlet 容器調用該方法。
public void contextDestroyed(ServletContextEvent sce)ServletContextEvent中的: getServletContext() 獲取ServletContext
此接口只有2個方法:
1.10 ServletRequestListener接口和HttpSessionListener接口小結
ServletRequestListener & HttpSessionListener
1).和ServletContextListener類似。2).利用ServletRequestListener. HttpSessionListener 以及ServletContextListener可以把request, session
及application的生命週期進一步的做一 瞭解。
>request: 是一一個請求, 當一個響應近回時,即被銷燬。當發送一個請求時被創建。注意,請求轉發的過程是一個request對象.
重定向是兩個請求
>session: 當第-次訪問WEB應用的一個JSP或Servlet 時,且該JSP或Servlet 中還需要創建session 對象。此時服務器會
創建-一個session對象。session銷燬: session 過期,直按調用session的invalidate方法,當前web應用被卸載(session可以被持久化)
申關閉瀏覽器,並不意味着session被銷燬,還可以通過sessionid找到服務器中的session 對象.JSESSIONID=F4119DE0FC93ED38E8EC83B24CFA3B81 http://1ocalhost :8989/day_ _40/ sess ion. jsp;jsessionid=F 4119DE0FC93ED38E8EC83B24CFA3B81
>application: 貫穿於當前的WEB應用的生命週期。當前WEB應用被加載時創建application對象,當前WEB應用被卸載時
銷燬application對象.|各自也只有2個方法:
Interface ServletRequestListener所有方法
Interface HttpSessionListener所有的方法
二、例子
監聽器中最重要的是ServletContextListener、ServletRequestListener和HttpSessionListener,其它的都不常用,故主要是以它們爲例。
2.1 例1 簡單的ServletContextListener
ServletContextListener接口中的方法輸出一些內容
2.1.1相關文件
2.1.2相關代碼
src-->com.hualinux.listener1-->HelloServletContextListener.java
package com.hualinux.listener1;
import javax.servlet.*;
public class HelloServletContextListener implements ServletContextListener{
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext 對象被創建");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext 對象被銷燬");
}
}
web-->WEB-INF-->web.xml
爲了方便,我把前章過濾器的配置註解掉。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- listener -->
<listener> <listener-class>com.hualinux.listener1.HelloServletContextListener</listener-class>
</listener>
</web-app>
web-->index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Test</title>
</head>
<body>
<h3>index html page</h3>>
</body>
</html>
2.1.3 運行效果
主要是看tomcat的輸出信息,如下圖:
上圖中,只出現對象被創建,如要輸出把網頁關閉也是不行的,可以停止tomcat試下,如下圖:
上面停止了tomcat,出現了“ServletContext 對象被銷燬”。
2.2 例2 簡單的ServletRequestListener和HttpSessionListener
我們可以在上面2.1的例子基礎上直接再繼承ServletRequestListener和HttpSessionListener接口,它們也是2個方法
2.2.1 相關文件入代碼
src-->com.hualinux.listener1-->HelloServletContextListener.java代碼修改如下:
package com.hualinux.listener1;
import javax.servlet.*;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class HelloServletContextListener implements ServletContextListener, ServletRequestListener,HttpSessionListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext 對象被創建");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext 對象被銷燬");
}
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
System.out.println("ServletRequest 對象被銷燬");
}
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
System.out.println("ServletRequest 對象被創建");
}
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
System.out.println("HttpSession 對象被創建");
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
System.out.println("HttpSession 對象被銷燬");
}
}
2.2.2 運行效果
主要也是看IDE最下方的tomcat的輸出信息
現在關閉網頁手工輸入:http://localhost:8080/index.html,多輸出了:
ServletRequest 對象被創建
ServletRequest 對象被銷燬
我們再打開一個陌生動態的網頁,如之前的hello.jsp,
http://localhost:8080/hello.jsp,發現多出了三行
ServletRequest 對象被創建
HttpSession 對象被創建
ServletRequest 對象被銷燬
關閉剛纔打開的新頁面,發現沒有變化,說明只關閉頁面,session不會被銷燬
把tomcat停止試下,發現只有“ServletContext 對象被銷燬”
說明session沒有被銷燬,需要手工操作,可以使用“session.invalidate();”方法
把hello.jsp修改爲
<%
session.invalidate();
%>
再運行訪問此頁面試下,多出了:
ServletRequest 對象被創建
HttpSession 對象被創建
HttpSession 對象被銷燬
ServletRequest 對象被銷燬
2.3 例3 簡單的Listener來觀察域對象生命週期
在 JavaWeb 應用中,被監聽的對象主要是:ServletContext、HttpSession、ServletRequest。
對應的監聽器爲ServletContextListener、ServletRequestListener、HttpSessionListener
2.3.1 相關文件
以上面“10.2.2例2”爲基礎,在web下新建立一個index.jsp,
修改一下test.jsp和com.hualinux.listener1-->HelloServletContextListener.java文件
2.3.2相關代碼
web-->index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>index</title>
</head>
<body>
<h3>index page</h3>
<a href="test.jsp">test page</a>
<%
request.setAttribute("requestKey","requestValve");
%>
</body>
</html>
web-->test.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
<html>
<head>
<title>test</title>
<meta charset="UTF-8">
</head>
<body>
<h3>Test Page</h3>
<%= request.getAttribute("requestKey") %>
</body>
</html>
src-->com.hualinux.listener1-->HelloServletContextListener.java
package com.hualinux.listener1;
import javax.servlet.*;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class HelloServletContextListener implements ServletContextListener, ServletRequestListener,HttpSessionListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext 對象被創建"+servletContextEvent.getServletContext());
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext 對象被銷燬"+servletContextEvent.getServletContext());
}
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
System.out.println("ServletRequest 對象被銷燬");
}
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
System.out.println("ServletRequest 對象被創建");
}
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
System.out.println("HttpSession 對象被創建");
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
System.out.println("HttpSession 對象被銷燬");
}
}
2.3.3效果
idea運行會自動轉到主頁
從上面發現“requestKey”是空的,沒有把index.jsp的“requestKey”傳過來。
查看IDE當訪問index.jsp頁面的時候發現,ide的tomcat信息如下:
ServletRequest 對象被創建
ServletRequest 對象被銷燬
請求馬上被註銷了,所以獲取不到requestKey的值。
解決方法:
通過請求轉發把index.jsp頁面的屬性轉發過來,所以在index.jsp添加一條
<jsp:forward page="test.jsp"/>
index.jsp整體代碼如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>index</title>
</head>
<body>
<h3>index page</h3>
<a href="test.jsp">test page</a>
<%
request.setAttribute("requestKey","requestValve");
%>
<jsp:forward page="test.jsp"/>
</body>
</html>
重啓tomcat,會
如果上面不用jsp:forward,也可以單獨寫一個servlet,
新建立一個類src-->com.hualinux.listener1-->TestServlet.java
package com.hualinux.listener1;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class TestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setAttribute("requestKey","requestvalue2");
//如果使用下面那個也會結果爲空
//resp.sendRedirect("test.jsp");
req.getRequestDispatcher("/test.jsp").forward(req,resp);
}
}
index.jsp做如下修改:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>index</title>
</head>
<body>
<h3>index page</h3>
<a href="test.jsp">test page</a>
<%--
<%
request.setAttribute("requestKey","requestValve");
%>
<jsp:forward page="test.jsp"/>
--%>
<br><br>
<a href="/testservlet">testServlet</a>
</body>
</html>
2.4 其它例子
主要還是注意一下session,這裏就不說了
>session: 當第-次訪間WEB應用的一個JSP或Servlet 時,且詼JSP或Servlet 中還需要創建session 對象。此時服務器會
創建-一個session 對象。
session銷燬: session 過期,直接調用session的invalidate方法,當前web應用被卸載(session可以被持久化) .
*關閉瀏覽器,並不意味着session 被銷燬,還可以通過sessionid 找到服務器中的session 對象.還有一個application,這個不太常用
>application: 貫穿於當前的WEB應用的生命週期。當前WEB應用被加載時創建application對象,當前WEB應用被卸載時銷燬application對象。|