我们的应用程序在30分钟后注销并被重定向到登录页面,我在web.xml中指定会话超时并使用requestProcessor进行重定向。我想向用户显示一条消息,说明会话在会话后过期到期,我该怎么做。自动注销? 我想提示页面上的错误消息“会话超时,请再次登录”。然后我怎么能检测到会话超时?任何方法会自动触发吗?
答案 0 :(得分:10)
创建一个活动检查器,检查每一分钟是否发生任何用户活动(mouseclick,keypress)并对服务器端执行心跳以在用户处于活动状态时保持会话处于活动状态,并在用户未处于活动状态时不执行任何操作。如果30分钟内没有活动(或者在服务器端设置了默认会话超时),则执行重定向。
这是一个启动示例,很少有jQuery的帮助来绑定click和keypress事件并触发ajax请求。
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
$(document).ready(function() {
$.active = false;
$('body').bind('click keypress', function() { $.active = true; });
checkActivity(1800000, 60000, 0); // timeout = 30 minutes, interval = 1 minute.
});
function checkActivity(timeout, interval, elapsed) {
if ($.active) {
elapsed = 0;
$.active = false;
$.get('heartbeat');
}
if (elapsed < timeout) {
elapsed += interval;
setTimeout(function() {
checkActivity(timeout, interval, elapsed);
}, interval);
} else {
window.location = 'http://example.com/expired'; // Redirect to "session expired" page.
}
}
</script>
创建一个Servlet
来监听/heartbeat
,基本上只做以下几点:
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
request.getSession();
}
让会话保持活力。
当您将登录用户存储在会话中时,只要会话过期,它就会“自动”注销。因此,您无需手动注销用户。
答案 1 :(得分:2)
创建一个实现HttpSessionListener
的Listener类,并在web.xml中定义它
这会在任何会话被销毁时通知您。使用sessionDestroyed()
方法。
请参阅此处的完整示例:
http://www.mkyong.com/servlet/a-simple-httpsessionlistener-example-active-sessions-counter/
答案 2 :(得分:0)
如果您正在使用servlet会话,则可以使用isNew()方法检查jsp / servlet返回的会话是否是新的。如果是,则用户的会话已过期,您可以显示相关消息。
答案 3 :(得分:0)
在JSP中包含一个javascript实用程序函数,每隔31分钟ping一次服务器。 上面提到的实用函数应该在内部使用setTimeout()JS函数。
setTimeout ( "checkServerSession()", /* intervalInMilliSeconds */ 31000);
请注意
checkServerSession()
是一个常规的JS函数,可以触发HTTP请求。如果请求成功,则会话存在,否则向用户显示提示。
答案 4 :(得分: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">