程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> 自定義session掃描器,session掃描器

自定義session掃描器,session掃描器

編輯:JAVA綜合教程

自定義session掃描器,session掃描器


為何要自定義session掃描器

由於服務器來管理session的銷毀不怎麼靠譜,因此很多網站都會自己定義一個session掃描器來管理session的創建和銷毀。

實現思路

首先,創建一個session掃描器類SessionScanner,然後繼承HttpSessionListener,在sessionCreated方法中,獲取session,這個時候我們需要創建一個容器,用來存放session,然後繼承ServletContextListener,在contextInitialized方法(在web應用啟動時執行此方法)中定義一個定時器,將一段時間內沒有用到的session銷毀。

代碼實現如下:

 1 package com.ccfdod.web.listener;
 2 
 3 import java.util.Collections;
 4 import java.util.Iterator;
 5 import java.util.LinkedList;
 6 import java.util.List;
 7 import java.util.ListIterator;
 8 import java.util.Timer;
 9 import java.util.TimerTask;
10 
11 import javax.servlet.ServletContextEvent;
12 import javax.servlet.ServletContextListener;
13 import javax.servlet.http.HttpSession;
14 import javax.servlet.http.HttpSessionEvent;
15 import javax.servlet.http.HttpSessionListener;
16 
17 public class SessionScanner implements HttpSessionListener,ServletContextListener {
18 
19     //這裡使用Collections.synchronizedList(List<T> list)是考慮到線程並發問題,因此將容器設置為線程安全的
20     //Collections為集合的幫助類,如發現具體的集合類不能提供某些功能,可查看該幫助類的方法,看是否存在該功能
21     //另外使用LinkedList而不使用ArrayList的原因是ArrayList底層為數據,用來做增刪改查不適合,效率較低
22     private List<HttpSession> list = Collections.synchronizedList(new LinkedList<HttpSession>());
23 
24     //定義一個鎖對象,用於解決線程並發時,session的添加和除去若同時進行,會引起定時器中對list的session操作時,產生迭代器並發修改異常
25     private Object lock = new Object();
26     public void contextInitialized(ServletContextEvent sce) {
27         //這裡使用Timer作為定時器,當然也可以使用其他的
28         Timer timer = new Timer();
29         timer.schedule(new MyTask(list,lock), 0, 30*1000);
30     }
31     
32     public void sessionCreated(HttpSessionEvent se) {
33         //第一次調用getSession時,服務器創建一個session
34         //但在jsp中,默認調用request.getSession()方法,創建一個session
35         //但可以在jsp文件的第一行,添加session="false",這樣在訪問jsp頁面時,就不會創建session了
36         HttpSession session = se.getSession();
37         System.out.println(session + "被創建了!!");
38         synchronized (lock) {  //鎖旗標
39             list.add(session);
40         }
41     }
42     public void sessionDestroyed(HttpSessionEvent se) {
43         System.out.println(se.getSession() + "被銷毀了");
44     }
45 
46     public void contextDestroyed(ServletContextEvent sce) {
47         
48     }
49 }
50 
51 class MyTask extends TimerTask{
52     private List list;
53     private Object lock;
54     public MyTask(List list,Object lock){
55         this.list = list;
56         this.lock = lock;
57     }
58     @Override
59     public void run() {
60         System.out.println("定時器執行!!");
61         synchronized (this.lock) {
62             //ListIterator為Iterator的子類,提供了對crud操作
63             ListIterator it = list.listIterator();
64             while(it.hasNext()){
65                 HttpSession session = (HttpSession) it.next();
66                 if((System.currentTimeMillis()-session.getLastAccessedTime())>30*1000){
67                     session.invalidate();
68                     //list.remove(session);  //迭代器並發修改異常
69                     //若對集合迭代,需要對集合進行crud操作時,使用迭代器的方法對集合進行crud
70                     it.remove();
71                 }
72             }
73         }
74     }
75 }

最後

將SessionScanner添加至web.xml中

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved