我是一個從汽車行業轉行IT的項目經理,我是Edward,如想了解更多,請關注我的公衆號【轉行項目經理的逆襲之路】。這幾天一直在努力實現這個功能,可是一直都有一點問題,即登出後立即登錄會報錯,最後用前端重定向刷新頁面來解決,回顧一下。
Listener端:
package cn.tedu.listner;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import cn.tedu.entity.User;
/**
* Application Lifecycle Listener implementation class OnlineUserCounter
*
*/
public class OnlineUserCounter implements HttpSessionListener {
private static Map<String, HttpSession>sessionMap = new HashMap<String, HttpSession>();
/**
* @see HttpSessionListener#sessionCreated(HttpSessionEvent)
*/
public void sessionCreated(HttpSessionEvent se) {
if (!sessionMap.containsKey(se.getSession().getId())) {
sessionMap.put(se.getSession().getId(), se.getSession());
}
ServletContext application = se.getSession().getServletContext();
application.setAttribute("num",sessionMap.size() );
}
public void sessionDestroyed(HttpSessionEvent se) {
if (sessionMap.containsKey(se.getSession().getId())) {
sessionMap.remove(se.getSession().getId());
}
ServletContext application = se.getSession().getServletContext();
application.setAttribute("num",sessionMap.size() );
}
}
xml文件會自動生成。
LogoutServlet裏中把session銷燬掉或設置時效讓它自行銷燬。
HttpSession session = request.getSession();
session.removeAttribute("user");
//銷燬session
// session.invalidate();
//銷燬session後再次嘗試登錄會報錯:java.lang.IllegalStateException: Cannot create a session after the response has been committed
//試試設置時效
//再嘗試登陸還是會報錯
session.setMaxInactiveInterval(1);
這裏,如果不銷燬session,是無法實現實時在線人數更新的,因爲session默認的時效期是30分鐘,關閉瀏覽器也還是會存在服務端。
但是問題來了
session銷燬後立即登錄就會出現這個錯誤:
可以想象一下,如果一個用戶註銷後無法再次登錄,肯定是不理想的。 但是我發現如果在地址欄輸入首頁地址,被filter打回來以後就可以正常登錄了,應該是創建了新的session,也就說,當前頁面是無法再創建新的session了,但是如果訪問其他頁面時創建了新的session則登錄頁面可以繼續使用新的session。
於是在前端登錄頁面進行如下修改:
<!-- 延時重定向頁面,起到創建新session的作用 -->
<script type="text/javascript">
window.setTimeout("window.location='http://localhost:8080/02Blog/HomeServlet'", 3000)
</script>
這樣頁面刷新以後即可正常登錄,不會報錯。
可以配合session銷燬的時效來設置延時時間,這樣就可以實現無縫銜接,用戶就可以在登出後正常登入了。