所谓用户交互是指:当用户单击某个东西时,可以检测会话超时,然后发送一些请求到服务器,然后服务器检查当前用户会话是否过期。
我需要的是,在不通知服务器任何内容(或不执行任何操作)的情况下,会话过期时服务器会自动检测并执行所需的操作。
谢谢, Raza
<%
int timeout = session.getMaxInactiveInterval();
response.setHeader("Refresh", timeout + "; URL = login.jsp");
%>
<jsp-property-group>
<display-name>all jsp</display-name>
<url-pattern>/users/*</url-pattern>
<include-prelude>/timedoutRedirect.jsp</include-prelude>
</jsp-property-group>
您可能需要根据项目规格调整引入URL。
当然,您可以通过实现文档范围的键盘和/或鼠标监听器以及具有超时的周期性方法在JavaScript中执行此操作。
var timeOut = 1000 * 60 * 30; // 30 minutes
var lastActivity = new Date().getTime();
var checkTimeout;
checkTimeOut = function(){
if(new Date().getTime() > lastActivity + timeOut){
// redirect to timeout page
}else{
window.setTimeout(checkTimeOut, 1000); // check once per second
}
}
现在你的全局监听器只需要在每个操作上将lastActivity设置为当前时间。
重新阅读问题后,您希望使用应用程序服务器的实际会话超时时间。这很困难,因为当您向服务器发送ajax请求时,您实际上会防止会话过期(除非有硬限制),因此我的答案可能仍然是最佳方法。
我曾经遇到过类似的问题,这是我解决的方法...
基本上,我使用JavaScript在客户端创建了一个会话计时器。我定期发送ajax调用(定时器小于实际服务器超时设置),以保持服务器上的会话活动。
然后,我创建了另一个计时器,在客户端倒数计时(设置为与实际服务器超时设置相同的时间)。如果该计时器到期,则向服务器发出ajax调用,运行session.invalidate(),然后转发到登录页面。每当有一些应该保持会话活动的操作时(例如鼠标单击、按键等),此计时器都会被重置。
无论是简单的servlet、spring-mvc还是spring-security,如果没有完美的客户端逻辑,自动注销都是不可能的。
考虑到应用程序将具有以下两种类型的请求:
自动注销需要非常精确的逻辑。以下是我的自动注销功能实现及其优点:
1. 在所需的JSP页面中包含以下自动注销脚本。
....
</body>
<jsp:include page="../template/autologout-script.jsp"></jsp:include>
</html>
2. 创建一个JSP页面,autologout-script.jsp,并添加以下代码。 注意:无需编辑/配置
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<script>
$(document).ready(function()
{
var timeOutTimeInSeconds = ${ timeOutTimeInSeconds };
var showTimerTimeInSeconds= ${ showTimerTimeInSeconds };
var sessionCheckIntervalId = setInterval(redirectToLoginPage, timeOutTimeInSeconds * 1000);
var timerDisplayIntervalId = setInterval(showTimer, (timeOutTimeInSeconds - showTimerTimeInSeconds) * 1000);
var badgeTimerId;
window.localStorage.setItem("AjaxRequestFired", new Date());
function redirectToLoginPage(){
//location.href = '<c:url value="/" />'+'${loginPageUrl}';
window.location.reload();
}
$(document).ajaxComplete(function () {
resetTimer();
});
$(window).bind('storage', function (e) {
if(e.originalEvent.key == "AjaxRequestFired"){
console.log("Request sent from another tab, hence resetting timer")
resetTimer();
}
});
function resetTimer()
{
showTimerTimeInSeconds= ${ showTimerTimeInSeconds };
console.log("timeOutTimeInSeconds : "+timeOutTimeInSeconds)
window.localStorage.setItem("AjaxRequestFired", new Date());
window.clearInterval(sessionCheckIntervalId);
sessionCheckIntervalId = setInterval(redirectToLoginPage, timeOutTimeInSeconds * 1000);
window.clearInterval(timerDisplayIntervalId);
timerDisplayIntervalId = setInterval(showTimer, (timeOutTimeInSeconds - showTimerTimeInSeconds) * 1000);
hideTimer();
}
function showTimer()
{
$('#sessionTimeRemaining').show();
$('#sessionTimeRemainingBadge').html(showTimerTimeInSeconds--);
window.clearInterval(timerDisplayIntervalId);
badgeTimerId = setInterval(function(){
$('#sessionTimeRemainingBadge').html(showTimerTimeInSeconds--);
}, 1000);
}
function hideTimer()
{
window.clearInterval(badgeTimerId);
$('#sessionTimeRemaining').hide();
}
});
</script>
3. 配置会话属性以配置超时设置 注意:在会话创建后进行配置。您可以实现HttpSessionListener的sessionCreated方法,并根据需要设置以下配置。
session.setMaxInactiveInterval(300);
session.setAttribute("timeOutTimeInSeconds", 300);
session.setAttribute("showTimerTimeInSeconds", 30);
4. 添加以下 HTML 以显示计时器。
注意:如果您擅长 CSS,可以将其移动到自动注销脚本模板页面中。因此,您可以避免在每个页面中都添加它。
包含 Bootstrap 或添加您自定义的 CSS。
<span class="badge badge-primary" title="click to keep session alive" id="sessionTimeRemaining"
onclick="ajaxSessionRefresh()" style="display:none;">
<i class="badge badge-danger" id="sessionTimeRemainingBadge" style="float:left">30</i>
<small>Refresh</small>
<i class="glyphicon glyphicon-refresh"></i>
</span>
这篇文章主要讲解了一个简单的自动登出实现方法。
你可以从我的Github仓库下载完整代码示例限制/需要改进
1. 如果最大允许会话为一,则如果会话来自另一个系统,则AJAX请求将失败。需要处理以重定向到登录页面。
2. 使用ajaxStart()而不是ajaxComplete(),以在服务器和浏览器之间具有精确的idleTime值同步。
要求
1. Jquery
response.setHeader("Refresh", "60; URL=login.jsp");
<meta http-equiv="refresh" content="60; url=login.jsp">