【发布时间】:2013-01-28 19:41:51
【问题描述】:
我正在使用数据库来存储用户详细信息,包括用户名和密码。它还有一个Security_check 列,默认为“logged_out”。
每当用户登录时,我都会从我验证用户(servlet)的页面中将Security_check 值修改为“logged_in”。每当用户点击注销按钮时,我都会明确地将Security_check 更改为其默认值。
但是当用户在没有退出的情况下关闭浏览器时,就会出现一个大问题,因为该用户的Security_check 列值仍然是“logged_in”,之后当该用户厌倦登录时,他们会得到一个错误消息指出您已经登录(因为我在允许任何用户登录之前检查了Security_check,在这种情况下他们已经登录)。所以他无法登录,也无法注销,因为当他关闭浏览器时会话已过期。那我该怎么办?
下面是 HttpSessionListener 类的代码,它不起作用:
package com.svc.session;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import java.sql.*;
import javax.servlet.http.HttpSession;
public class Session_Invalidator implements HttpSessionListener
{
public Session_Invalidator()
{
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
}
catch(Exception e)
{
}
}
public void sessionCreated(HttpSessionEvent se)
{
}
public void sessionDestroyed(HttpSessionEvent se)
{
HttpSession session = se.getSession();
String uName = session.getAttribute("userName").toString().trim();
Connection con = null;
PreparedStatement stmt = null;
try
{
// i am using a space between the colon and odbc because if
// I don't it will be converted to smile, so ignore the space
con = DriverManager.getConnection("jdbc: odbc:CMS","","");
stmt = con.prepareStatement("update Users set security_check=default where login_name=?");
stmt.setString(1, uName);
int no = stmt.executeUpdate();
} catch(Exception e)
{
}
}
}
【问题讨论】:
-
请更具体地告诉我们,究竟是什么不起作用。你调试过你的代码吗?当会话停用时,方法
sessionDestroyed()是否被调用?有什么例外吗?如果您单独调用它,您的数据库访问代码是否有效?独立地,如果没有明确的注销,我认为禁止重新登录不是一个好主意。即使您在会话停用时自动注销有效,用户也必须等待自动会话超时(通常为 20 到 30 分钟)。 -
一切正常,但是当我关闭浏览器时,db(也是 sessiondestroyed)没有调用。但它像往常一样在默认会话到期时间之后调用。但在此期间用户无法登录(因为数据库中的 security_check 已登录),所以我如何在浏览器关闭/系统突然关闭后尽快更新
-
这是正常行为。服务器永远不会知道用户是关闭浏览器还是只是在厨房喝咖啡。因此,服务器将保持会话打开,直到用户返回并继续工作的情况下超时。因此,
sessionDestroyed()方法总是在会话超时时调用,而不是在浏览器关闭时调用。
标签: java jsp session servlets session-timeout