Человекопонятные URL-адреса в Wicket

 

Одним из недостатков Wicket на сегодняшний день являются нечитаемые URL-адреса. В этой статье рассмотрены способы обойти этот недостаток, найденные разработчиками Энтерры. Конечная цель – получить URL-адреса типа REST.
При использовании описанных способов важно учитывать разницу между версиями Wicket. Подробнее об этом здесь: http://cwiki.apache.org/WICKET/migrate-13.html

 

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

WebApplication.mount().

Для этого в конструкторе org.apache.wicket.protocol.http.WebApplication выполним следующее:

mount("/pages", PackageName.forPackage(HomePage.class.getPackage()));
mount("/pages/user", PackageName.forPackage(ProfilePage.class.getPackage()));
mount("/pages/user/personal", PackageName.forPackage(MyAccountPage.class.getPackage()));

про аргументы mount() можно почитать в документации

В этом случае URL-адреса страниц, расположенных на смонтированных пакетах, выглядят следующим образом:

http://localhost:9090/wicket_res/app/pages/HomePage
http://localhost:9090/wicket_res/app/pages/user/personal/MyProfilePage

параметры для этих страниц выглядят так:
http://localhost: 9090/wicket_res/app /pages/user/personal/MyProfilePage/tab/Basic
использованный параметр: tab=Basic.

Чем удобен этот способ?
1. все страницы могут быть смонтированы в тот же самый момент, как они созданы в пакете
2. при добавлении BookmarkablePageLink, связывании с подобной страницей нужный вид приобретается сразу же.

Формы

Создать адрес такого типа для форм (наследников org.apache.wicket.markup.html.form.Form) уже значительно сложнее, т.к. Wicket после обработки формы переходит по адресу, указанному в атрибуте “action” тэга формы в методе onComponentTag.

tag.put("action",Strings.replaceAll(urlFor(IFormSubmitListener.INTERFACE),"&","&"));

При поиске расширения формы возможны 2 результата обработки формы:
1. форма заполнена без ошибок и onSubmit() работает;
2. форма содержит ошибки (замеченные валидаторами) и срабатывает onError();
Эта статья предлагает следующие алгоритмы решения:

Простой способ:
В первом случае в методе onSubmit() настроим передачу на нужную страницу:

setResponsePage(YouPage.class, [parameters]);

Если мы установили смонтированную (см. выше) страницу, то URL будет таким, какой и требуется.

Но в Wicket 1.3 с формой Stateless эта установка не пройдёт, потому что Wicket 1.3, в отличие от 1.2, в методе класса org.apache.wicket.RequestCycle

public final CharSequence urlFor(final Component component,final RequestListenerInterface listener)

следит за соответствием формы условию

(listener != IRedirectListener.INTERFACE && component.isStateless() && page.isBookmarkable())

и генерирует URL в атрибуте action формы, используя BookmarkableListenerInterfaceRequestTarget.

При этому URL выглядит так:
http://localhost:9090/wicket_res/app/pages/FormPage/wicket:interface/%3A0%3Aform%3A%3AIFormSubmitListener%3A%3A

По поводу проблемы:
“но теперь Wicket не сохраняет монтирование в пути, мы хотели остановиться на этом ранее,но не нашли времени, добавьте rfe для 1.4 и мы посмотрим позже” –

http://www.nabble.com/Can-I-get-a-%27Nice-URL%27-when-form-validation-fails–tf4020865.html#a11420378

Примечание:
Чтобы сделать страницу доступной для добавления в закладки, она должна иметь конструктор YouPage(final PageParameters) помимо всех остальных.
Чтобы форма обрабатывалась как Stateless, метод getStatelessHint должен возвращать true.

Во втором случае, можно воспользоваться onError() в форме. Но при этому будут утеряны все FeedbackMessages. Т.к. начиная с версии 1.3, эти сообщения хранятся в сессии (конструкция доступна через Session.get().getFeedbackMessages().hasErrorMessageFor(component)), наверняка должен существовать способ вытащить их оттуда и установить вручную. Пока что этот способ не найден.

Остается надеяться, что в будущих версиях Wicket разработчики добавят функционал, снимающий проблему нечитаемости URL-адресов.

Сложный способ:
Изменяя реализацию Application.newRequestCycleProcessor на нужную стратегию (реализации org.apache.wicket.request.IRequestCodingStrategy) можно добиться многого.

По поводу:
“если Вы действительно настроены на подобное поведение, тогда, как я и сказал, используйте stateless-страницы и формы; если не работает – подключайте свою стратегию кодинга, но я абсолютно не представляю, что может Вам потребоваться, и насколько просто это написать” –

http://www.nabble.com/Can-I-get-a-%27Nice-URL%27-when-form-validation-fails–tf4020865.html#a11420378

Альтернативный способ.
Просто используйте AJAX вместо форм. Проблема читаемости URL-адресов отпадёт сама собой.