我是一个从汽车行业转行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销毁的时效来设置延时时间,这样就可以实现无缝衔接,用户就可以在登出后正常登入了。