使用 Wicket 处理会话超时
Handle session time out with Wicket
我正在处理 wicket 遗留项目,我正在尝试修复会话超时的错误。
基本上我想在会话超时后重定向到自定义错误页面。
这就是我所做的:
web.xml :
<session-config>
<session-timeout>1</session-timeout>
</session-config>
在应用程序中 class:
@Override
public void init() {
super.init();
getApplicationSettings().setPageExpiredErrorPage(ErrorMessagePage.class);
这是行不通的。我的意思是在会话超时后,什么也没有发生。
我做错了什么?
编辑 04.05.20
根据 Martin 的反馈,我尝试实现会话有效性检查器:
public class SessionValidityChecker implements IRequestCycleListener {
@Override
public void onBeginRequest(RequestCycle cycle) {
HttpServletRequest request = (HttpServletRequest) cycle.getRequest().getContainerRequest();
boolean sessionValid = request.isRequestedSessionIdValid();
if (!sessionValid) {
cycle.setResponsePage(SessionExpiredPage.class);
}
}
}
并在 Application.class
public void init() {
super.init();
getRequestCycleListeners().add(new SessionValidityChecker());
}
此外,我可能应该在我的第一个 post 中指定的是我使用 wicket SignInPanel 进行身份验证。超时后,我希望用户注销并重定向到特定页面。
这是我用上面的代码尝试过的,但是在会话超时后,没有发生重定向。更糟糕的是,用户仍然登录。我错过了什么?
您将页面过期误认为是会话过期。
有状态页面存储在 PageStore(磁盘)中,存储可能会增长到某个预定义的大小。达到此大小后,将删除最旧的页面以为最新的页面腾出空间。
如果您的用户在某个时候多次使用浏览器后退按钮,Wicket 将针对已删除的页面抛出 PageExpiredException。
在您的情况下,当会话过期时,Web 服务器(例如 Tomcat)通常会创建一个新的。如果您的应用程序启用了身份验证,那么它将检测到新的 http 会话中没有经过身份验证的用户,并且很可能会将用户重定向到登录页面。
如果没有适当的身份验证,Wicket 将创建请求页面的新实例并呈现它。您可以通过将 PageSettings#recreateBookmarkablePagesAfterExpiry
更改为 false
来更改此设置
(参见 https://github.com/apache/wicket/blob/79f63f66eb588a5d69e9feff7066f1244f61f387/wicket-core/src/main/java/org/apache/wicket/settings/PageSettings.java#L46)
您可以使用 javax/servlet/http/HttpServletRequest.html#isRequestedSessionIdValid() 方法来查找请求是否带有过期的 JSESSIONID cookie/url。如果为 false,则 Web 服务器刚刚创建了一个新的 HttpSession。您可以在 Wicket 的 IRequestCycleListener#onBeginRequest()
中进行检查
我正在处理 wicket 遗留项目,我正在尝试修复会话超时的错误。 基本上我想在会话超时后重定向到自定义错误页面。 这就是我所做的:
web.xml :
<session-config>
<session-timeout>1</session-timeout>
</session-config>
在应用程序中 class:
@Override
public void init() {
super.init();
getApplicationSettings().setPageExpiredErrorPage(ErrorMessagePage.class);
这是行不通的。我的意思是在会话超时后,什么也没有发生。 我做错了什么?
编辑 04.05.20
根据 Martin 的反馈,我尝试实现会话有效性检查器:
public class SessionValidityChecker implements IRequestCycleListener {
@Override
public void onBeginRequest(RequestCycle cycle) {
HttpServletRequest request = (HttpServletRequest) cycle.getRequest().getContainerRequest();
boolean sessionValid = request.isRequestedSessionIdValid();
if (!sessionValid) {
cycle.setResponsePage(SessionExpiredPage.class);
}
}
}
并在 Application.class
public void init() {
super.init();
getRequestCycleListeners().add(new SessionValidityChecker());
}
此外,我可能应该在我的第一个 post 中指定的是我使用 wicket SignInPanel 进行身份验证。超时后,我希望用户注销并重定向到特定页面。
这是我用上面的代码尝试过的,但是在会话超时后,没有发生重定向。更糟糕的是,用户仍然登录。我错过了什么?
您将页面过期误认为是会话过期。 有状态页面存储在 PageStore(磁盘)中,存储可能会增长到某个预定义的大小。达到此大小后,将删除最旧的页面以为最新的页面腾出空间。 如果您的用户在某个时候多次使用浏览器后退按钮,Wicket 将针对已删除的页面抛出 PageExpiredException。
在您的情况下,当会话过期时,Web 服务器(例如 Tomcat)通常会创建一个新的。如果您的应用程序启用了身份验证,那么它将检测到新的 http 会话中没有经过身份验证的用户,并且很可能会将用户重定向到登录页面。
如果没有适当的身份验证,Wicket 将创建请求页面的新实例并呈现它。您可以通过将 PageSettings#recreateBookmarkablePagesAfterExpiry
更改为 false
来更改此设置
(参见 https://github.com/apache/wicket/blob/79f63f66eb588a5d69e9feff7066f1244f61f387/wicket-core/src/main/java/org/apache/wicket/settings/PageSettings.java#L46)
您可以使用 javax/servlet/http/HttpServletRequest.html#isRequestedSessionIdValid() 方法来查找请求是否带有过期的 JSESSIONID cookie/url。如果为 false,则 Web 服务器刚刚创建了一个新的 HttpSession。您可以在 Wicket 的 IRequestCycleListener#onBeginRequest()
中进行检查