Вопрос по java – Как я могу сделать AjaxLink Wicket без гражданства?

8

Я создаю веб-приложение Wicket, которое будет обрабатывать много одновременных запросов. Я настроил тестовую среду и некоторые jmeter-скрипты для проведения нагрузочного тестирования, и я заметил, что могу уменьшить нагрузку на процессор и память моего приложения, если сделаю большинство страниц без сохранения состояния.

Я добавил код в метод onBeforeRender () самой большой страницы, чтобы показать мне, какие из компонентов заставляют мою страницу сохранять состояние. Вот код, который я имею для обнаружения этого:

<code>@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;
            }
        });
    }
}
</code>

В выводе я вижу, что поведение с состоянием вызвано AjaxLinks, используемыми некоторыми из существующих компонентов на страницах:

<code>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
</code>

Я пытался добавить методы getStatelessHint (), возвращающие & quot; true & quot; в некоторых местах, но это, похоже, не помогает. Я также проверил исходный код Wicket AjaxLink, его суперклассы и некоторый окружающий код, но, похоже, не могу понять, почему AjaxLink должен сохранять состояние во всех случаях.

В моем случае AjaxLink находится на странице без сохранения состояния, и ссылка не сохраняет состояние. Как я могу заставить Wicket понять, что этот AjaxLink может не иметь состояния?

Спасибо за вашу помощь, Рольф

Edit: Accepted answer works with Wicket 1.4.19.

В файл maven pom.xml добавлено следующее:

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

Изменены все компоненты, которые расширили «AjaxLink». расширить "StatelessAjaxFallbackLink".

Не забудьте добавить следующее в свой класс WicketApplication, это сэкономит вам время на устранение неполадок:

<code>@Override
protected IRequestCycleProcessor newRequestCycleProcessor() {
    return new StatelessWebRequestCycleProcessor();
}
</code>

Обратите внимание, что StatelessForm и другие вещи без сохранения состояния по какой-то причине не работают из повторителя (например, «ListView»).

Ваш Ответ

2   ответа
10

когда вы добавляете к ней поведение Ajax (AjaxLink использует AjaxEventBehavior). Это происходит потому, что когда вы щелкаете ссылку, Wicket пытается найти экземпляр страницы на сервере, затем найти компонент ссылки внутри него и, наконец, выполнить свой метод обратного вызова - например, по щелчку(). Без сохранения страницы невозможно найти экземпляр поведения ajax и выполнить его метод обратного вызова.

Вы можете использовать поведение и компоненты Ajax Jolira (https://github.com/jolira/wicket-stateless). Они работают немного по-другому - когда вы нажимаете на AjaxLink Jolira, вызов Ajax создает совершенно новый экземпляр страницы, находит в нем только что созданный StatelessAjaxLink, выполняет его метод обратного вызова, в конечном итоге использует AjaxRequestTarget для добавления компонентов / javascript для Ajax ответ и отбрасывает вновь созданный экземпляр страницы (это сборщик мусора). Следующий Ajax-запрос делает то же самое с совершенно новым экземпляром страницы.

Кто-то может спросить: «Почему код Джолиры отсутствует в ядре Wicket?» - потому что это дает частичное решение. Например: нажатие на statelessAjaxLink1 создает новую страницу, выполняет onClick () для нового экземпляра StatelessAjaxLink, где PanelA заменяется PanelB, и добавляет эту панель (PanelB) в AjaxRequestTarget. Вкратце: нажатие на эту ссылку заменяет тело панели на странице. Если PanelB имеет StatelessAjaxLink2 внутри себя, эта ссылка не может быть найдена. Зачем ? Поскольку нажатие на него создаст новый экземпляр страницы, и у этого нового экземпляра будет PanelA, а не PanelB, и, таким образом, нет способа найти StatelessAjaxLink2 для выполнения его метода onClick ().

Если ваш сценарий достаточно прост и компоненты Jolira охватывают ваши случаи, используйте их. Просто знайте, что более сложный сценарий может провалиться.

Error: User Rate Limit Exceeded Rolf
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Rolf
Error: User Rate Limit Exceededcentral.maven.org/maven2/org/wicketstuff/wicketstuff-stateless
3

AjaxFallbackLink упоминается накалитка викии связанный с ним проект github, по которому можно перейти по следующим ссылкам. Не уверен, что это полностью решит вашу проблему, но это может быть, по крайней мере, поучительно.

Подобный подход был опробован для калитки 6, но автор предупреждает, что он экспериментальный. КодВот, Я не пытался его использовать, и поэтому не могу ручаться за него.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded

Похожие вопросы