gpt4 book ai didi

java - Wicket 口 6 : empty PageParameters when recreating a page after expiration

转载 作者:行者123 更新时间:2023-11-30 02:37:08 25 4
gpt4 key购买 nike

我们在使用 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,我们需要对其进行修复。

以下是对我们的发现和一些问题的详细解释。

发生的情况是这样的:

  1. 用户打开一个页面(有状态)并使其在浏览器选项卡中保持打开状态。
  2. 用户打开其他页面
  3. 尽管 session 仍在运行,但第 1 步中的原始页面已从页面存储中逐出(即过期)。
  4. 用户返回到初始浏览器选项卡并单击链接。这是链接的代码:

    AjaxLink<Void> link = new AjaxLink<Void>("link") {
    @Override
    public void onClick(AjaxRequestTarget target) {
    showWindow(dataModel, window, target);
    }
    };
    add(link);
  5. 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;
    }

    因此,根据请求构建的 ListenerInterfaceRequestHandlerPageParametersnull

  6. 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() 方法),但至少页面不会爆炸,只是自行刷新。

问题是:

  1. 发生这种情况是因为我们做错了什么还是 Wicket 中的错误?
  2. 我们应用的修复是否合格?我猜想 https://issues.apache.org/jira/browse/WICKET-4594 引入的变化不只是为了好玩
  3. 知道我们只有有状态页面,我们的修复是否会破坏任何内容?

最佳答案

这是 Wicket 6.x 的限制,已在 7.x 中实现。6.x 没有进行此更改,因为我们不确定它是否不会默默地破坏某人的应用程序。IIRC 如果升级期间需要,可以重写 7.x 中的方法以恢复到旧的行为。AFAIK 没有人提示 7.x 中的这一变化,所以我想将其向后移植到 6.x (6.27.0) 是可以的,但是 Wicket 的活跃开发人员不再使用 6.x,而且有人这样做的机会是相当低。建议您升级到7.x。它很稳定,有许多新功能和错误修复。在那之前,我猜您的选择是使用此请求映射器的自定义版本。

关于java - Wicket 口 6 : empty PageParameters when recreating a page after expiration,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42751254/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com