在用户关闭浏览器并走开的情况下,我想在会话超时时记录日志。例如,作为系统引起的注销而不是用户请求(我已经有工作和测试的代码来记录用户请求的注销)。如果浏览器关闭,JSF会话过期阶段监听器
由于用户没有主动提交请求(特别是如果它只是现在未使用的会话在服务器上超时的问题),我不认为过滤器是可能的。这可以通过阶段监听器完成吗?如果是的话,你能提供一些见解或骨架,或至少指出我如何做到这一点的正确方向。
我的理解是,服务器上的会话仍然是活动的,直到它超时或其他一些机制使其无效。因此,我假设阶段侦听器也将能够告诉您是否作为登录方法的一部分,在用户以全新视图,其他机器等重新登录之前终止任何现有会话。
我是确定研究,但至少要开始时指向正确的方向。 :)
在第二个注意:是否有可能区分会话超时和视图过期?
想我会后我结束了基于该建议的解决方案:
public class ElsSoulardSessionListener implements HttpSessionListener {
@EJB
private SessionLogger sessionLogger = new SessionLogger();
private SessionLogDTO sessionData = new SessionLogDTO();
private ElsDateTimeFunctions ts = new ElsDateTimeFunctions();
private static final Logger logger = Logger.getLogger(ElsSoulardSessionListener.class.getSimpleName());
@Override
public void sessionCreated(HttpSessionEvent se) {
// Nothing to do yet
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
logger.log(Level.FINE, "SESSION DESTROYED LISTENER");
HttpSession session = se.getSession();
finalizeUserSessionLog(session);
}
/**
* Utility method to finalize user's session log entry. Returns
* early if the session log isn't found or more than one is returned.
* @param session
*/
private void finalizeUserSessionLog(HttpSession session) {
String sessionId = session.getId();
LogoutReasonType logoutReason = (LogoutReasonType) session.getAttribute("logoutreason");
if (logoutReason == null) {
logoutReason = LogoutReasonType.SESSION_TIMEOUT;
}
try {
sessionData = sessionLogger.findBySessionId(sessionId);
} catch (NonexistentEntityException | UnexpectedResultSetSizeException ex) {
logger.log(Level.WARNING, " sessionDestroyed ", ex);
return;
}
Calendar now = ts.getUtcDateTimeAsCalendar();
sessionData.setLogoutTimestamp(now);
sessionData.setLogoutReason(logoutReason);
sessionLogger.update(sessionData);
}
}
您可以使用[HttpSessionListener](http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpSessionListener.html )来处理会话更改。 – 2012-08-05 17:03:11