[英]How can I make Wicket's “AjaxLink” Stateless?
我正在構建一個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;
}
});
}
}
在輸出中,我看到有狀態行為是由頁面中某些現有組件使用的AjaxLink引起的:
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可以是無狀態的?
謝謝你的幫助,羅爾夫
編輯:接受的答案適用於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創建一個新頁面,在其中PanelA替換為PanelB的StatelessAjaxLink的新實例上執行onClick(),並將此面板(PanelB)添加到AjaxRequestTarget。 簡而言之:單擊此鏈接將替換頁面中面板的主體。 如果PanelB內部有StatelessAjaxLink2,則此鏈接不可用。 為什么? 因為單擊它將創建一個新的Page實例,這個新實例將具有PanelA,而不是PanelB,因此無法找到StatelessAjaxLink2來執行其onClick()方法。
如果您的場景足夠簡單並且Jolira的組件涵蓋了您的案例,那么請使用它們。 請注意,更復雜的情況可能會失敗。
在wicket wiki上引用了無狀態AjaxFallbackLink
代碼,以及一個相關的github項目,您可以從那里獲得以下鏈接。 不確定這會完全解決你的問題,但它至少可能是有益的。
Wicket 6也嘗試過類似的方法,但作者警告說它是實驗性的。 代碼在這里 。 我沒有嘗試使用它,因此無法保證它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.