我的要求是通过弹出窗口通知用户,说明用户会话即将在x秒内超时,以防用户在网页上执行任何活动。
除此要求外,还要在弹出窗口中动态减少x秒值。
我使用的环境是Java EE。
答案 0 :(得分:11)
利用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>
要神奇地减少消息内部的时间,那么你需要一个带有div的覆盖,而不是基本alert()
,你可以通过HTML DOM树控制内容并使用另一个{{1}在1秒内动态更改文本。
请注意,此脚本必须由setTimeout()
提供,才能使EL正常工作。因此,您需要将脚本放在JSP页面的HTML JspServlet
中,或者如果您确实希望将所有JS放在单独的<head>
文件中,那么您需要让{{1处理任何*.js
请求。
答案 1 :(得分:1)
我不认为Java / Java EE在这方面会有所帮助,因为这需要在客户端处理(即使用JavaScript)。我能想到的一个解决方案是设置一种在服务器超时前几分钟通知用户的计时器。
在谷歌搜索时,我发现Eric Pascarello的Update User's Session with AJAX博客文章(以及重新加载的版本Updating User Session with Ajax - Round 2)准确描述了这样的解决方案(并使用XMLHttpRequest
来更新会话) 。他的Ajax会话管理脚本可用here。
答案 2 :(得分:0)
可能是简单的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.如果最大允许会话数为1,则如果会话是从另一个系统进行的,则AJAX请求将失败。需要处理它以重定向到登录页面。
2.使用ajaxStart()而不是ajaxComplete()在服务器和浏览器之间实现idleTime值的精确同步。
要求
1. jQuery
response.setHeader("Refresh", "60; URL=login.jsp");
<meta http-equiv="refresh" content="60; url=login.jsp">