1、監聽器
(1)什麼是監聽器
servlet規範當中定義的一種特殊的元件,用來監聽servlet容器産生的事件并進行相應的處理。
事件主要有兩大類:
1)生命周期相關的事件:
當容器建立或者銷毀了request,session,servletContext(servlet上下文)時産生的事件。
2)綁訂相關的事件:
當容器調用了request,session,servlet上下文的setAttribute,removeAttribute方法時産生的事件。
(2)如何寫一個監聽器
step1,寫一個java類,實作相應的監聽器接口。(依據事件類型選擇相應的接口,比如監聽session的建立或者銷毀,使用HttpSessionListener接口)
step2,在監聽器接口方法裡面,編寫相應的處理邏輯。
step3,注冊(在web.xml檔案裡面,配置監聽器)。
(3)servlet上下文
1)什麼是servlet上下文?
容器一啟動,會為每一個web應用建立唯一的一個符合ServletContext接口要求的對象。該對象就是servlet上下文。
該對象有兩個特點:
a,唯一性:一個web應用一個servlet上下文。
b,一直存在: 隻要容器不關閉或者應用沒有被解除安裝,servlet上下文會一直存在。
2)如何獲得servlet上下文
可以通過GenericServlet,ServletConfig,FilterConfig,HttpSession提供的getServletContext方法來獲得servlet上下文。
3) 作用
a,綁訂資料
setAttribute(String name,Object obj);
Object getAttribute(String name);
removeAttribute(String name);
注意:
request,session,servlet上下文都提供了綁訂資料相關的方法,但是有兩個差別:
差別1:綁訂資料生存的時間不一樣,servlet上下文 > session > request。
差別2: 資料共享的範圍不一樣。
request對象綁訂的資料隻有同一個請求所涉及的各個元件可以通路(轉發,過濾器);
session對象綁訂的資料隻有同一個會話所涉及的各個元件可以通路;
servlet上下文綁訂的資料是同一個應用所有的元件都可以通路。
盡量優先使用生命周期短的,比如能用request解決,就不要用session。
b,通路全局的初始化參數(同一個應用内部的所有的servlet/filter都可以通路的初始化參數)。
step1,使用
<context-param>
<param-name>company</param-name>
<param-value>name</param-value>
</context-param>
step2,使用
String ServletContext.getInitParameter( "company");
c,獲得實際部署時的實體路徑
String getRealPath(String path);
2、案例:統計線上人數
index.jsp:
<%@page pageEncoding="utf-8"
contentType="text/html;charset=utf-8" %>
<html>
<head></head>
<body style="font-size:40px;">
這是首頁<br/>
目前系統線上人數是:
<%=application.getAttribute("count") %>
<br/>
<a href="logout" target="_blank" rel="external nofollow" >退出</a>
</body>
</html>
web.xml添加配置:
<listener>
<listener-class>web.CountListener</listener-class>
</listener>
<servlet>
<servlet-name>LogoutServlet</servlet-name>
<servlet-class>web.LogoutServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LogoutServlet</servlet-name>
<url-pattern>/logout</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
LogoutServlet.java:
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class LogoutServlet extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession();
session.invalidate();//銷毀session
}
}
CountListener.java:
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class CountListener implements HttpSessionListener{
private int count = 0; // 計數器
/*
* session一建立,容器就會調用sessionCreated方法。
* HttpSessionEvent:事件對象
*/
public void sessionCreated(HttpSessionEvent arg0) {
System.out.println("session created.");
count ++;
HttpSession session = arg0.getSession();
ServletContext sctx = session.getServletContext();
//将人數(count)綁訂到servlet上下文
sctx.setAttribute("count", count);
}
/*
* session銷毀之後,容器會調用sessionDestroyed方法。
*/
public void sessionDestroyed(HttpSessionEvent arg0) {
System.out.println("session destroyed.");
count --;
HttpSession session = arg0.getSession();
ServletContext sctx = session.getServletContext();
//将人數(count)綁訂到servlet上下文
sctx.setAttribute("count", count);
}
}