我们遇到过Wicket 6(即版本6.22.0)的问题。它看起来像是在这里修复的:https://issues.apache.org/jira/browse/WICKET-5068
简而言之:在页面过期后,Wicket尝试通过调用带有页面类和PageParameters
作为参数的构造函数来重构它,但PageParameters
是(错误地)为空,即使某些参数与请求。
After Wicket session timeout - pageParameters are null似乎与同一问题有关。
WICKET-5068修复了Wicket 7,但我们正在使用Wicket 6,我们需要修复它。
以下是对我们的调查结果和一些问题的冗长解释。
以下是发生的事情:
用户返回初始浏览器标签并点击链接。以下是链接的代码:
AjaxLink<Void> link = new AjaxLink<Void>("link") {
@Override
public void onClick(AjaxRequestTarget target) {
showWindow(dataModel, window, target);
}
};
add(link);
当BookmarkableMapper
从请求构建IRequestHandler
时,会调用以下方法(AbstractBookmarkableMapper:294):
protected PageParameters getPageParametersForListener(PageInfo pageInfo, PageParameters pageParameters)
{
if (pageInfo.getPageId() != null)
{
// WICKET-4594 - ignore the parsed parameters for stateful pages
return null;
}
return pageParameters;
}
因此,根据请求构建的ListenerInterfaceRequestHandler
null
为PageParameters
。
Wicket开始处理点击。它尝试恢复被点击链接所属的页面,这是通过以下方法完成的(PageProvider,从第252行开始):
private void resolvePageInstance(Integer pageId, Class<? extends IRequestablePage> pageClass,
PageParameters pageParameters, Integer renderCount)
{
IRequestablePage page = null;
boolean freshCreated = false;
if (pageId != null)
{
page = getStoredPage(pageId);
}
if (page == null)
{
if (pageClass != null)
{
page = getPageSource().newPageInstance(pageClass, pageParameters);
freshCreated = true;
}
}
if (page != null && !freshCreated)
{
if (renderCount != null && page.getRenderCount() != renderCount)
{
throw new StalePageException(page);
}
}
pageInstanceIsFresh = freshCreated;
pageInstance = page;
}
当页面从页面存储中逐出时,以下语句的条件成立:
if (page == null)
因此它尝试从类和页面参数创建页面实例:
page = getPageSource().newPageInstance(pageClass, pageParameters);
但此处pageParameters
为null
(因为第5项中的getPageParametersForListener()
)。所以页面构造函数变为空PageParameters
并失败,因为它需要一些id。
以下是在页面构造函数中从PageParameters
中提取id的代码:
pageParameters.get("id").toLong()
以下是产生的异常(仅显示顶行,因为其余部分不相关):
org.apache.wicket.util.string.StringValueConversionException: Unable to convert 'null' to a long value
at org.apache.wicket.util.string.StringValue.toLong(StringValue.java:664)
因此,在我们的案例中,getPageParametersForListener()
方法可以恢复已过期页面的处理。
尝试解决此问题,我们已将BookmarkableMapper
替换为我们的自定义实现:
public class BookmarkableMapperThatSavesPageParametersForListener extends BookmarkableMapper {
@Override
protected PageParameters getPageParametersForListener(PageInfo pageInfo, PageParameters pageParameters) {
return pageParameters;
}
}
我们在WebApplication#init()
方法中挂载:
mount(new BookmarkableMapperThatSavesPageParametersForListener());
它似乎解决了我们遇到的问题:链接点击不会触发处理程序(onClick()
方法),但至少页面不会爆炸并只刷新自己。
问题:
答案 0 :(得分:2)
这是Wicket 6.x的限制,已在7.x中实施。 6.x没有得到这个改变,因为我们不确定它是否会默默地打破某个人的应用程序。 IIRC可以覆盖7.x中的方法,以便在升级期间根据需要恢复旧行为。 AFAIK没有人在7.x中抱怨这个变化,所以我想将它向后移植到6.x(6.27.0)是可以的,但是Wicket的活跃开发者都不再使用6.x而且有人这样做的机会是相当低。 建议您升级到7.x.它很稳定,有许多新功能和错误修复。 在那之前,我想您的选择是使用此请求映射器的自定义版本。