我的要求是通过弹出窗口通知用户用户会话即将在 x 秒内超时,以防用户未在网页上执行任何活动。
除了这个要求是在弹出窗口中动态减少 x 秒的值。
我使用的环境是 Java EE。
我的要求是通过弹出窗口通知用户用户会话即将在 x 秒内超时,以防用户未在网页上执行任何活动。
除了这个要求是在弹出窗口中动态减少 x 秒的值。
我使用的环境是 Java EE。
利用HttpSession#getMaxInactiveInterval()
和setTimeout()
。在此特定用途中不需要 Ajax,除非您想推迟每个客户端活动(轮询)的超时。
基本示例:
<script>
var secondsBeforeExpire = ${pageContext.session.maxInactiveInterval};
var timeToDecide = 15; // Give client 15 seconds to choose.
setTimeout(function() {
alert('Your session is about to timeout in ' + timeToDecide + ' seconds!')
}, (secondsBeforeExpire - timeToDecide) * 1000);
</script>
要神奇地减少消息中的时间,那么alert()
您需要一个带有 div 的叠加层,而不是基本的,您可以在其中通过 HTML DOM 树控制内容,并setTimeout()
在 1 秒内使用另一个来动态更改文本。
请注意,此脚本必须由EL 提供服务JspServlet
才能使 EL 工作。因此,您需要将脚本放在<head>
JSP 页面的 HTML 中,或者如果您真的想将所有 JS 放在一个单独的*.js
文件中,那么您还需要让JspServlet
处理任何*.js
请求。
我不认为 Java/Java EE 在这里真的很有帮助,因为这需要在客户端处理(即使用 JavaScript)。我能想到的一个解决方案是设置一种计时器,在服务器超时前几分钟通知用户。
在谷歌搜索时,我发现 Eric Pascarello 的Update User's Session with AJAX博客文章(以及重新加载的版本Updating User Session with Ajax - Round 2)准确地描述了这种解决方案(并使用 anXMLHttpRequest
来更新会话)。他的 Ajax 会话管理脚本可在此处获得。
如果没有完美的客户端逻辑,它可能是简单的 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 可以移到 autologout-script 模板页面。因此,您可以避免在每个页面中添加它。
包括引导程序或添加您的自定义 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 存储库下载工作示例
Autologout using simple servlet example
Autologout using spring-security java configuration example
Autologout using spring-security xml configuration example
需要的限制/改进
1. 如果最大允许会话是一个,如果会话来自另一个系统,AJAX 请求将失败。需要对其进行处理以重定向到登录页面。
2. 使用 ajaxStart() 而不是 ajaxComplete() 在服务器和浏览器之间精确同步 idleTime 值。
需求
1.jquery
response.setHeader("Refresh", "60; URL=login.jsp");
<meta http-equiv="refresh" content="60; url=login.jsp">