在将一些遗留代码从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
。https://github.com/apache/wicket/blob/master/wicket-core/src/main/java/org/apache/wicket/protocol/http/PageExpiredException.java L31
似乎我只需要通过始终使用以下语法来解决这个问题:
setResponsePage(new MyPage());
这不是世界末日,因为至少我不需要传入任何参数,以触发所需的"Go to session expired page"行为。