spring - 一次只有一个用户使用整个 Web 应用程序 - Spring Boot
问题描述
在 Spring Boot 应用程序中,一次只有一个用户应该使用某个页面(我们称之为home.jsp
)。another_home.jsp
如果其他用户在访问相同的 url 时出现,则应将其重定向到不同的页面(我们称之为)。用户没有登录,只是按原样使用应用程序。任何可以使用的策略都可以home.jsp
是先到先服务或任何其他策略。
如果有多个用户同时使用应用程序,则只有一个用户应该使用 home.html,而其他所有用户都应该使用another_home.jsp
.
由于应用程序中不需要登录,我相信我需要匿名会话。此外,会话需要在一段时间不活动后过期。我已经搜索了 spring security 但找不到任何东西。
解决方案
您需要创建一个服务器端状态,该状态要么为空,要么存储当前声明的访问者的标识符/home.jsp
。这可以是单例 Bean 上的字段,也可以是数据库中的实体。它必须自动过期,否则它将永远阻止新访问者提出索赔。只要状态为空,第一个访问者标识符就会存储在这个状态中。从那一刻起,您会将所有其他访问者重定向到another_home.jsp
所以控制器代码将是这样的
if(visitorHoldsTheClaim()) {
return "home.jsp"
} else if (noClaimActive()) {
createClaimForVisitor();
return "home.jsp"
} else {
return "redirect:/another_home.jsp"
}
根据您的实现,这些方法将做不同的事情。
我通常建议不要使用服务器端会话状态(在Roy Fieldings Dissertation中对此进行了更多介绍),但对于您的用例,您需要一种方法来识别多个请求的访问者。会话肯定是实现这一目标的一种非常简单的方法。您至少可以通过一次只创建一个会话来最小化会话使用 - 为持有声明的访问者创建的会话。在这种情况下,您永远不会有超过一个开放会话,并且拥有该会话的访问者就是持有该声明的访问者。
所以在这种情况下,实现将是这样的:
if(currentUserHasASession()) { // checks if the current user has a session, but !!!does not create a new session if it does not exist!!! careful, HttpServletRequest.getSession(true) would create it!
return "home.jsp"
} else if (serverHasNoSessions()) { // https://stackoverflow.com/questions/49539076/how-can-i-get-a-list-of-all-sessions-in-spring
createSessionForUser(); // HttpServletRequest.getSession(true)
return "home.jsp"
} else {
return "redirect:/another_home.jsp"
}
请记住,这仅在您不在其他地方创建会话时才有效。所以你必须配置 Spring Boot/Spring Security 以不创建会话。如何使spring boot永远不会发出会话cookie?
还要记住并发性。例如,如果您只有一个服务器实例,您可以将此代码放入一个synchronized
方法中,以避免两个访问者同时创建声明。
推荐阅读
- asp.net-core - 为什么 RenderPage 无法识别?
- c# - 绘制的线一直被删除或替换
- ios - 如何使用多种功能填充搜索栏和表格视图
- java - 如何使中心 MaterialAlertDialogBuilder 对齐标题、消息和按钮
- python-3.x - 从多进程调用的子进程未完成
- azure-cosmosdb - Azure Cosmos DB 查询
- python - pyparsing 可选元素导致 asDict 方法的值错误
- javascript - webpack 生产模式“构建” - 强制浏览器不读取缓存文件/重建新文件
- spring - 如何创建具有 3 个或更多不同客户端来源的 Mono?
- javascript - 使用 lodash 比较两个对象数组,不包括属性