java - 在 Wicket 9 中,当用户的会话在某些页面中过期时,他们会被重定向到登录页面而不是 Session Expired 页面
问题描述
在将一些遗留代码从 Wicket 1.5 升级到 Wicket 9 时,我发现重定向到“会话已过期”通知页面似乎被部分破坏了。
我在主应用程序文件中有以下语句,它以前总是可以工作:
getApplicationSettings().setPageExpiredErrorPage(MyErrorPage.class);
这是应该触发重定向到“MyErrorPage”的场景:
- 用户成功登录并进入任何菜单选项。
- 他们坐了一会儿,什么也不做,他们的会话超时。
- 在这段不活动之后,他们单击链接或尝试提交表单。
- 此时,它们应该被重定向到“MyErrorPage”。
在点 (1) 中调用的菜单选项 - 让我们称之为 MyMenuPage - 可以使用两种可能的语法类型调用:
setResponsePage(MyMenuPage.class);
或者:
setResponsePage(new MyMenuPage(params));
如果使用 SECOND 语法调用原始菜单页面,用户似乎只会被重定向到我的自定义错误页面。
如果原始页面是使用 FIRST 语法调用的,则用户会被直接发送到登录页面,而不会对他们的页面已过期的事实进行任何解释。
请有人告诉我如何在两种类型的页面中获得相同的结果 - 这不是无状态的,因为用户已经登录。
解决方案
页面过期和 http 会话过期是有区别的。
正如 PageExpiredException 的 javadoc [I] 解释的那样,有三个可能的原因:
- 该页面从未存储在那里,例如在存储过程中发生错误
- http 会话已过期,因此与此会话相关的所有页面也将被删除
- 由于超出了存储大小,页面实例已被删除
Wicket 将所有有状态的页面存储在磁盘上。稍后当您使用此类页面时,例如通过单击链接,Wicket 会加载页面实例、执行单击并呈现响应。
如果 http 会话已过期,那么很可能您的身份验证策略会启动并重定向到登录页面,甚至无需尝试加载旧页面。如果您Component#continueToOriginalDestination()
在成功登录后使用,则用户将被导航到旧页面的新实例。
总结一下:
- 如果 http 会话过期,那么您的应用程序将重定向到 LoginPage
- 如果页面实例已过期,则默认情况下,Wicket 将创建它的新实例(请参阅
PageSettings#setRecreateBookmarkablePagesAfterExpiry(boolean)
)或显示配置的getApplicationSettings().setPageExpiredErrorPage(MyPage.class);
将被呈现
要调试在您的情况下发生的事情,请在以下位置放置一些断点:
- https://github.com/apache/wicket/blob/6a7e4c3d770324f125fbf43615c7708b67c8d8c5/wicket-core/src/main/java/org/apache/wicket/Component.java#L1061
- https://github.com/apache/wicket/blob/6a7e4c3d770324f125fbf43615c7708b67c8d8c5/wicket-auth-roles/src/main/java/org/apache/wicket/authroles/authentication/AuthenticatedWebApplication.java#L134
推荐阅读
- tomcat - Tomcat Parrellel 部署命名
- android - 片段到片段转换:推迟EnterTransition() 不起作用
- amazon-web-services - 如何将 AWS 资源 ID 插入应用程序配置文件
- c# - 在视图中保存和操作 2 个模型列表
- javascript - 当键盘弹出时,如何使 React-Native 应用程序优雅地响应
- sql - 如何使用两个表进行sql查询
- android - 如何搜索蓝牙设备?
- asp.net-core - .Net Core - 在解决方案中引用另一个项目会阻止系统和其他依赖项被识别
- sql - 我可以使用 ODBC 连接在 Excel 中使用 Select DISTINCT 函数来避免导入重复的列条目吗?
- excel - Excel 2016:重复行填充 4 个重复数字的系列