在Java Web应用程序中,如何在会话结束后自动注销用户以登录页面?

在Java Web应用程序中,如何在会话结束后自动注销用户以登录页面?,java,servlets,jakarta-ee,servlet-filters,stripes,Java,Servlets,Jakarta Ee,Servlet Filters,Stripes,要求是,若用户会话失效,它应该自动将用户重定向到登录页面,而无需进行任何服务器调用。定期调用服务器的解决方案不适合,因为它会增加服务器负载。编写servlet过滤器怎么样?若客户端向服务器发送新请求,他将被重定向到登录页面。 下面是一个例子: public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

要求是,若用户会话失效,它应该自动将用户重定向到登录页面,而无需进行任何服务器调用。定期调用服务器的解决方案不适合,因为它会增加服务器负载。

编写servlet过滤器怎么样?若客户端向服务器发送新请求,他将被重定向到登录页面。 下面是一个例子:

public void doFilter(ServletRequest req, ServletResponse res,
        FilterChain chain) throws IOException, ServletException {
        HttpSession session = request.getSession(false);//false means: don't create if it doesn't exist
        if(session != null && !session.isNew()) {
            chain.doFilter(request, response);
        } else {
            HttpServletResponse httpResponse = (HttpServletResponse) response;
            httpResponse.sendRedirect("/login.jsp");//your login page
        }
}

我明白你的意思了,你不想为管理会话打任何额外的电话,事实上这是一个好问题

无论是简单的servlet、spring mvc还是spring security,如果没有完善的客户端逻辑,都不可能自动注销。
正在考虑的应用程序将具有两种类型的请求

  • AJAX和
  • 表单提交/页面重新加载
自动注销需要非常精确的逻辑。用以下内容展示我的自动功能实现

优势。
1.不使用额外的呼叫/请求来实现此目的。如果超过10k的活跃用户和额外呼叫实现自动注销,则考虑性能影响。
2.使用标签的单线配置。
3.即使用户打开多个选项卡或多个窗口,也能完美工作。
4.它会在会话失效30秒之前通知您,所以如果您已填写表单但未提交,则可以保持会话处于活动状态(通过单击扩展会话)。因此,用户不太可能丢失未保存的数据

用法
1。在所需的JSP页面中包含自动注销脚本,如下所示。

。。。。
2。创建一个JSP页面autologout-script.JSP并添加以下代码。 注意:无需编辑/配置


$(文档).ready(函数()
{
var timeOutTimeInSeconds=${timeOutTimeInSeconds};
var showTimerTimeInSeconds=${showTimerTimeInSeconds};
var sessionCheckIntervalId=setInterval(重定向到loginpage,timeouttimeunseconds*1000);
var timerDisplayIntervalId=setInterval(showTimer,(timeOutTimeInSeconds-showTimerTimeInSeconds)*1000);
巴氏锥虫;
setItem(“AjaxRequestFired”,new Date());
函数redirectToLoginPage(){
//location.href=''+'${loginPageUrl}';
window.location.reload();
}
$(文档).ajaxComplete(函数(){
重置计时器();
});
$(窗口).bind('storage',函数(e){
if(e.originalEvent.key==“AjaxRequestFired”){
log(“从另一个选项卡发送的请求,因此重置计时器”)
重置计时器();
}
});
函数resetTimer()
{
showTimerTimeInSeconds=${showTimerTimeInSeconds};
log(“timeOutTimeInSeconds:+timeOutTimeInSeconds”)
setItem(“AjaxRequestFired”,new Date());
clearInterval(sessionCheckIntervalId);
sessionCheckIntervalId=setInterval(重定向到LoginPage,timeOutTimeInSeconds*1000);
window.clearInterval(timerDisplayIntervalId);
timerDisplayIntervalId=设置间隔(showTimer,(timeOutTimeInSeconds-showTimerTimeInSeconds)*1000);
hideTimer();
}
函数showTimer()
{
$('#sessionTimeRemaining').show();
$('sessionTimeRemainingBadge').html(showTimerTimeInSeconds--);
window.clearInterval(timerDisplayIntervalId);
badgeTimerId=setInterval(函数(){
$('sessionTimeRemainingBadge').html(showTimerTimeInSeconds--);
}, 1000);
}
函数hideTimer()
{
窗口清除间隔(badgeTimerId);
$('#sessionTimeRemaining').hide();
}
});
3。将会话属性配置为配置超时设置 注意:在创建会话后配置此选项。您可以实现HttpSessionListener sessionCreated方法,并根据需要设置以下配置

session.setMaxInactiveInterval(300);

session.setAttribute("timeOutTimeInSeconds", 300);
session.setAttribute("showTimerTimeInSeconds", 30);

4。在下面添加html以显示计时器。
注意:如果您擅长CSS,可以将其移动到自动编译脚本模板页面。因此,您可以避免在每个页面中添加此内容。
包括引导或添加自定义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>
     &nbsp; 
     <small>Refresh</small>
     <i class="glyphicon glyphicon-refresh"></i>
</span>
  • 在HTML中设置元刷新标记(不适用于AJAX请求)
  • 
    
  • 配置活动检查器 通过重复的AJAX请求保持会话活动。跟踪空闲时间并在超时后发出注销请求。
    毫无疑问,这是一个逻辑简单的好方法。但我只想写下我的观察结果。
    • 性能影响如果每分钟发出2个请求以保持会话活动和50k活跃用户。每分钟10万个请求
    • 选项卡间通信如果两个选项卡打开,一个选项卡正在接收活动,而另一个选项卡未接收活动,则该选项卡将发出注销请求并使会话无效,即使其他选项卡中存在活动。(但可以处理)
    • 强制注销方法这是一种客户端控制服务器使会话无效的方法

  • 在我的情况下,向服务器发送请求是不可行的。@ManojKumar,如果用户不能向服务器发送请求,那么他将如何使用您的应用程序?
    response.setHeader("Refresh", "60; URL=login.jsp");
    
    <meta http-equiv="refresh" content="60; url=login.jsp">