9 декабря 2010 года

При переносе программного обеспечения, обеспечивающего функциональность ресурсов altailand.ru, altai-flowers.ru и других, с JSF на Wicket пришлось решить ряд проблем.

Одной из таких проблем явилась известная проблема генерации по умолчанию "неудобоваримых" ссылок (URL) от Wicket при навигации по сайту. Возможно, в версии 1.5 или выше проблема ссылок будет решена, но в текущих релизах Wicket 1.4.* она имеет место быть.

В нашем случае также нужно было обеспечить доступ извне к ресурсам по ссылкам типа:

Index.jsp?id=2&page=3 или Detail.jsp?id=2&code=r567834

Решение этого вопроса оказалось, на удивление, несложным. Достаточно было лишь добавить в метод init() класса Application строки:

mount(new QueryStringUrlCodingStrategy("Index.jsp", Index.class));
mount(new QueryStringUrlCodingStrategy("Detail.jsp", Detail.class));

Передача параметров странице происходит в ее конструкторе:

public Index(PageParameters parameters)

Поэтому с организацией их обработки также сложностей не возникло.

Гораздо сложнее оказалось исключить из URL имя веб-приложения. Например, при использовании виртуального сервера с доменным именем altailand.ru внешние ссылки должны были иметь следующий вид:

http://altailand.ru/Index.jsp?id=2&page=3
http://altailand.ru/Detail.jsp?id=2&code=r567834

Но в Wicket подобные ссылки не работали, ибо он неизменно добавлял к ним имя приложения на сервере и правильные с его точки зрения ссылки выглядели так:

http://altailand.ru/altailand/Index.jsp?id=2&page=3
http://altailand.ru/altailand/Detail.jsp?id=2&code=r567834

Это было недопустимо и начались исследования по решению этой проблемы. Ожидаемого простого решения найдено не было. Применяемое решение было обнаружено в статье Эрика ван Остена (Erik van Oosten):

http://blog.jteam.nl/2010/02/24/wicket-root-mounts/

Основано оно на трюке с динамической подстановкой нового URL у запроса, после его выполнения.

Два пакета с кодом Эрика ван Остена были добавлены к проекту:

nl.jteam.rootmount
nl.jteam.rootmount.coding

В класс Application было добавлено:

private List<RootMountedUrlCodingStrategy> rootMounts = new ArrayList<RootMountedUrlCodingStrategy>();
 protected IRequestCycleProcessor newRequestCycleProcessor() {
   return new RootWebRequestProcessor(rootMounts);
 }
 private class RootMounted extends RootMountedMixdedParamUrlCodingStrategy {
   public RootMounted() {
     super(app,Index.class, new String[]{});
   }
   public boolean accepts(String rawPath) {
     String name = RawPathUtil.firstPathPath(rawPath);
     return name != null && name.equalsIgnoreCase(app);
   }
 }

А в метод init() класса Application была добавлена строка:

rootMounts.add(new RootMounted());

Отметим, что переменная app в методе accept(String rawPath) и в конструкторе RootMounted() класса RootMounted - удаляемое имя приложения.

Использованное решение было протестировано с разными серверами - контейнерами сервлетов. Оно успешно работало в jetty v7.2.2, в tomcat v6.0.29 и в glassfish v3.01 и не работало (по непонятной причине) в glassfish v2.1


Комментарии (2)

11.12.2011 14:24:45, Аркадий
http://altailand.ru/Index.jsp?id=2&page=3 - а почему jsp? В wicket же нет jsp-страниц. Только Java и html.

11.12.2011 22:55:12, Георгий Гуляев, Барнаул, сайт
Да, конечно. Но при переходе на Wicket мне нужно было сохранить структуру сайта, не нарушив уже существующие внешние ссылки на его страницы. Поэтому пришлось заставить Wicket работать с такими ссылками. Файла Index.jsp реально не было. Были Index.java, Index.html и т.д. При этом, как показано в статье, Index.jsp монтировался в Index.class, то есть в Index.java и Index.html.

Автор (*):Город:
Эл.почта:Сайт:
Текст (*):