当前位置: 首页 > 面试题库 >

如何使Wicket的“ AjaxLink”成为无状态?

程赞
2023-03-14
问题内容

我正在构建一个Wicket
Web应用程序,它将必须处理很多同时请求。我已经设置了一个测试环境和一些jmeter脚本来进行负载测试,并且我注意到,如果我将大多数页面设置为无状态,则可以减少应用程序的CPU和内存占用。

我已将代码添加到最大页面的onBeforeRender()方法中,以向我显示哪些组件导致页面变为有状态。这是我用于检测的代码:

@Override
protected void onBeforeRender() {    
    if (!getSession().isTemporary()) {
        visitChildren(Component.class, new IVisitor<Component>() {
            @Override
            public Object component(Component component) {
                String pageClassName = AbstractStatelessBasePage.this.getClass().getName();
                if (!component.isStateless()) {

                    String msg = pageClassName+" is stateful because of stateful component " + component.getClass().getName() + " with id " + component.getId() + ".";

                    List<IBehavior> behaviourList = component.getBehaviors();
                    for (IBehavior iBehavior : behaviourList) {
                        if (!iBehavior.getStatelessHint(component)) {
                            msg += "\n\t" + "The component has stateful behaviour: " + iBehavior.getClass().getName();
                        }
                    }
                    LOG.error(msg);
                }

                checkedPages.add(pageClassName);
                return CONTINUE_TRAVERSAL;
            }
        });
    }
}

在输出中,我看到有状态行为是由页面中某些现有组件使用的AjaxLinks引起的:

ERROR - AbstractStatelessBasePage$1.component(45) | HomePage is stateful because of stateful component InfoGrid$InfoButton with id infoButton.
    The component has stateful behaviour: org.apache.wicket.ajax.markup.html.AjaxLink$1

我尝试在一些地方添加getStatelessHint()方法以返回“
true”,但这似乎无济于事。我还检查了AjaxLink的Wicket源代码,其超类和一些周围的代码,但是我似乎无法发现为什么AjaxLink在所有情况下都必须是有状态的。

就我而言,AjaxLink处于其他无状态页面中,并且链接不存储状态。如何使Wicket理解此AjaxLink可以是无状态的?

感谢您的帮助,Rolf

编辑:接受的答案适用于Wicket 1.4.19。

在maven pom.xml中添加了以下内容:

<dependency>
    <groupId>com.jolira</groupId>
    <artifactId>wicket-stateless</artifactId>
    <version>1.0.8</version>
</dependency>

将扩展“ AjaxLink”的所有组件更改为扩展“ StatelessAjaxFallbackLink”。

不要忘记将以下内容添加到WicketApplication类,这将为您节省一些故障排除时间:

@Override
protected IRequestCycleProcessor newRequestCycleProcessor() {
    return new StatelessWebRequestCycleProcessor();
}

请注意,出于某种原因,StatelessForm和其他无状态内容无法在转发器(如“ ListView”)中运行。


问题答案:

当您向页面添加Ajax行为时,该页面将变为有状态的(AjaxLink使用AjaxEventBehavior)。这是因为当您单击链接时,Wicket会尝试在服务器上找到页面实例,然后在其中找到链接组件,最后执行其回调方法-
例如onClick()。如果不存储页面,则无法找到ajax行为实例并执行其回调方法。

您可以使用Jolira的Ajax行为和组件(https://github.com/jolira/wicket-stateless)。它们的工作原理略有不同-
当您单击Jolira的AjaxLink时,Ajax调用将创建页面的全新实例,在其中找到新创建的StatelessAjaxLink,执行其回调方法,最终使用AjaxRequestTarget为Ajax响应添加组件/
javascript,丢弃新创建的页面实例(已被垃圾回收)。下一个Ajax请求对一个全新的页面实例执行相同的操作。

有人会问:“为什么Jolira的代码不在Wicket核心中?”
-因为它提供了部分解决方案。例如:单击statelessAjaxLink1创建一个新的Page,在StatelessAjaxLink的新实例上执行onClick(),其中PanelA被PanelB替换,并将此面板(PanelB)添加到AjaxRequestTarget。简而言之:单击此链接将替换页面中面板的主体。如果PanelB内部有一个StatelessAjaxLink2,则此链接是找不到的。为什么呢
因为单击它会创建Page的新实例,并且此新实例将具有PanelA,而不是PanelB,因此无法找到StatelessAjaxLink2执行其onClick()方法。

如果您的场景足够简单,并且Jolira的组件可以满足您的要求,则可以使用它们。请注意,更复杂的方案可能会失败。



 类似资料:
  • 问题内容: 沿以下几行创建用于下载文件的按钮/链接非常方便: 和 但是,我想 触发仅在单击按钮/链接时下载文件的生成 。换句话说,单击后,我将调用一个方法来生成文件(在本例中为Pentaho报告),将其放置在临时位置并返回指向该文件的指针。然后我告诉那个使用它。问题是, 这有可能 吗? 目前,我们有类似下面的代码,可以正常工作,但是我对是否可以代替它感兴趣。 (如果有区别,请参见1.4.18节。)

  • 问题内容: 出于调试的原因,我想一时兴起,将某些信息 包含在HTML注释中包含 的Wicket页面的HTML输出中。 输出将类似于… …其中“ 1234”是一些有趣的动态创建的信息。 我尝试了,但无济于事: →Wicket抱怨HTML页面缺少ID为“ foo”的元素 括入→这样的部分不能包含带有 →Wicket完全不输出标签 → 并逃脱 因此,您可以轻松地使用Wicket进行此操作,还是应该忘掉它

  • 在我开发的一个应用程序上,我试图为应用程序的页面保留一个好的、可读的url。我从url开始,如下所示:http://somedomain.com/context/?param1=value getRequestCycle()。setResponsePage(新建其他页面(obj1、obj2、pageParameters) 在这里,目标1和目标2是初始化页面所需的对象。正如我从这篇文章中理解的那样,

  • 问题内容: 我正在使用Yii框架,并且有小问题。然后,我将部分 CHtml :: ajaxLink 包括 在内 ,链接停止以ajax的形式工作,引发标准点击并执行重定向到另一页的操作。谁能帮我?谢谢。 问题答案: 只是一个假设,但是在将partialRender与javascript一起使用时,请打开processOutput。调用renderPartial时,它是第四个参数: 使用异步调用或其他

  • 我们正在运行一个Flink集群来计算历史上数TB的流式数据。数据计算有一个巨大的状态,我们使用键控状态-RocksDb后端的值和映射状态。在工作计算的某个时候,工作绩效开始下降,输入和输出率下降到几乎为0。此时,可以在日志中看到诸如“与Taskmanager通信X超时错误”之类的异常情况,但作业甚至在之前就已被破坏。 我想我们面临的问题是RocksDb的磁盘后端。随着作业状态的增长,需要更频繁地访