Servlet_6

滿心歡喜!發表於2020-10-21

Servlet_6

一、監聽器

Servlet 事件監聽器是一個實現了特定介面的 Java 程式,這個程式專門用於監聽 Web 應用中 ServletContext、HttpSession 和 ServletRequest 等物件的建立和銷燬過程、監聽這些域物件屬性的修改以及感知繫結到 HttpSession 域中的某個物件的狀態。
Servlet 規範中定義了八種監聽器,這八種監聽器的型別及作用.
在這裡插入圖片描述

HttpSessionActivationListener 的描述中涉及活化和鈍化的概念,
HttpSession 物件從記憶體中轉移至硬碟的過程稱為鈍化.
HttpSession 物件從持久化狀態變為執行狀態的過程稱為活化。
根據監聽事件的不同,可以將表中的監聽器分為如下三類

1.用於監聽域物件建立和銷燬的事件監聽器(ServletContextListener 介面、HttpSessionListener 介面、ServletRequestListener 介面)。

2.用於監聽域物件屬性增加和刪除的事件監聽器(ServletContextAttributeListener 介面、HttpSessionAttributeListener 介面、ServletRequestAttributeListener 介面)。

3.用於監聽繫結到 HttpSession 域中某個物件狀態的事件監聽器(HttpSessionBindingListener 介面、HttpSessionActivationListener 介面)
在 Servlet 規範中,這三類事件監聽器都定義了相應的介面,在編寫事件監聽器程式時只需實現對應的介面即可。在使用監聽程式時,Web 伺服器會根據監聽器所實現的介面,把它註冊到被監聽的物件上,當觸發了某個物件的監聽事件時,Web 容器將會呼叫 Servlet 監聽器與之相關的方法對事件進行處理。

二、HttpSessionListener監聽器統計網站線上人數

在許多網站或者軟體應用中都有統計當前線上人數這一功能。在通常情況下,當一個使用者進入網站時就會建立一個 HttpSession 物件,而當使用者離開網站時,HttpSession 物件就會被銷燬。在 Servlet 的八種監聽器中,HttpSessionListener 監聽器就可以監聽 Web 應用中 HttpSession 物件的建立和銷燬過程。因此,可以使用實現了 HttpSessionListener 介面的監聽器統計網站的當前線上人數。
1.建立監聽器[新建一個java類實現HttpSessionListener介面,重寫方法]

package com.listener;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class OnLineListener implements HttpSessionListener {
    private int count = 0;//用於統計線上人數的變數
    //監聽HttpSession物件的建立
	@Override
	public void sessionCreated(HttpSessionEvent hse) {
	   count++;//Session物件建立時count變數加1
	   ServletContext context = hse.getSession().getServletContext();
	   context.setAttribute("count", new Integer(count));
		
	}
    //監聽HttpSession物件的銷燬
	@Override
	public void sessionDestroyed(HttpSessionEvent hse) {
		count--;//Session物件銷燬時count變數減1
		   ServletContext context = hse.getSession().getServletContext();
		   context.setAttribute("count", new Integer(count));	
	}
}

在 OnlineListener.java 中,首先定義了一個用於統計線上人數的成員變數 count。當每次監聽到 HttpSession 物件建立時,count 成員變數會加 1。當每次監聽到 HttpSession 物件銷燬時,count 成員變數會減 1在每次修改 count 成員變數後,還應該將 count 成員變數的值儲存到 ServletContext 物件中,以便其他Servlet程式可以從 ServletContext 物件中取出 count 成員變數,從而在頁面上顯示當前線上使用者數量。
2.在 web.xml 檔案中,配置 OnlineListener 事件監聽器

<listener>
      <listener-class>com.listener.OnLineListener</listener-class>
  </listener>
  1. 建立首頁和登出頁面
package com.servlet;
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 HomeServlet extends HttpServlet{

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doPost(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		req.setCharacterEncoding("utf-8");
		resp.setCharacterEncoding("utf-8");
		PrintWriter out =resp.getWriter();
		out.println("<html>");
		out.println("<head><meta charset=\"utf-8\"><title>HomeServlet</title></head>");
		out.println("<body><center>");
		Object  countobj=req.getSession().getServletContext().getAttribute("count");
		int count=(int)countobj;
		out.println("<h1>當前線上人數:"+count+"</h1>");
		out.println("<h2><a  href=\"logout\">安全退出</a></h2>");
		out.println("</center></body>");
		out.println("</html>");
		out.close();
	}
	

}
package com.servlet;
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 LogOutServlet extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doPost(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		req.setCharacterEncoding("utf-8");
		resp.setCharacterEncoding("utf-8");
		//銷燬session物件
		req.getSession().invalidate();
		PrintWriter out=resp.getWriter();
		out.println("<html>");
		out.println("<head><meta charset=\"utf-8\"><title>LogOutServlet</title></head>");
		out.println("<body><center>");
		out.println("<h1>你已經退出本系統!</h1>");
		out.println("</center></body>");
		out.println("</html>");
		out.close();
	}	
}
<servlet>
  	<servlet-name>home</servlet-name>
  	<servlet-class>com.servlet.HomeServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>home</servlet-name>
  	<url-pattern>/home</url-pattern>
  </servlet-mapping>
  <servlet>
  	<servlet-name>logout</servlet-name>
  	<servlet-class>com.servlet.LogOutServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>logout</servlet-name>
  	<url-pattern>/logout</url-pattern>
  </servlet-mapping>

測試http://localhost:8080/TestListener/home
在這裡插入圖片描述

安全退出以後的效果
在這裡插入圖片描述