Лучшие практики реализации фронт-контроллера с использованием сервлетов Java

Предположим, у нас есть проект со следующей структурой:

web
  articles
    main.jsp
    sidearts.jsp
    central.jsp
  forum
    main.jsp
  css
  js
  WEB-INF
    web.xml

Обратите внимание, что на данный момент у нас еще нет фронт-контроллера.

После развертывания с некоторым аспектом (пусть это будет «asdf») мы можем получить доступ к нашим страницам, используя следующие URL-адреса:

http://localhost:8080/asdf/articles/main.jsp
http://localhost:8080/asdf/forum/main.jsp

and so on..

main.jsp генерирует html и включает в себя sidearts.jsp (посредством jstl c:import или любым другим способом)

А что будет после добавления фронт-контроллера?

Предположим, у нас есть сервлет ArticlesController, который отвечает за отправку
некоторых запросов и имеет следующее отображение:

<servlet>
  <servlet-name>ArtsController</servlet-name>
  <servlet-class>org.forstackoverflow.ArticlesController</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>ArtsController</servlet-name>
  <url-pattern>/articles/*</url-pattern>
</servlet-mapping>

Теперь, когда мы запрашиваем URL http://localhost:8080/asdf/articles/main, ArticlesController обрабатывает этот запрос и пытается включить article/main.jsp. И в этот момент начинается бесконечный цикл, потому что /articles/* отображается на ArtsController.

Каково правильное решение описанной проблемы?

Мои варианты:

1) сделать маппинги для всех jsp-файлов (не думаю, что это приемлемо)

2) изменить названия каталогов (статьи->искусство); но затем мы получаем много новых URL-адресов (например, http://localhost:8080/asdf/arts/main.jsp), и я думаю, что это может быть источником ошибок.


person Roman    schedule 27.07.2009    source источник
comment
В комментариях я могу опубликовать примеры из POEAA, когда вернусь домой.   -  person Thomas Owens    schedule 27.07.2009
comment
Из любопытства, по какой причине вы хотите реализовать свой собственный (на основе сервлета) фронт-контроллер? Почему бы не выбрать одну из многих доступных сред MVC с открытым исходным кодом.   -  person Richard Kettelerij    schedule 28.07.2009


Ответы (2)


Возможно, вы путаете сервлеты с фильтрами. С сервлетом не будет бесконечного цикла. Ваши страницы JSP всегда будут отображаться с помощью точных шаблонов, либо явно (если они были предварительно скомпилированы), либо неявно (через путь к файлу JSP относительно корня веб-приложения, если они не были предварительно скомпилированы). Это означает, что ваш «articles/main.jsp» будет фактически сервлетом со следующим отображением:

<servlet-mapping>
  <servlet-name>name_does_not_matter_here</servlet-name>
  <url-pattern>/articles/main.jsp</url-pattern>
</servlet-mapping>

Если ваш сервлет ArticlesController сопоставлен с /articles/*, произойдет следующее:

http://localhost:8080/asdf/articles/main URL будет обрабатываться вашим сервлетом, поскольку он не соответствует шаблону для JSP. Однако http://localhost:8080/asdf/articles/main.jsp URL-адрес, который соответствует обоим шаблонам, будет сопоставлен со страницей JSP, а не с сервлетом, поскольку контейнер сервлета ВСЕГДА будет предпочитать точное совпадение совпадению с подстановочными знаками (это часть спецификации J2EE).

person ChssPly76    schedule 27.07.2009
comment
Есть ли способ развернуть один и тот же сервлет несколько раз без необходимости его дополнительных копий? Скажем, я пишу какую-то CMS и хочу, чтобы ею могли пользоваться два клиента — допустим ли такой вариант использования? Это контролируется через web.xml? - person Chris K; 28.07.2009
comment
Я не совсем уверен, что вы имеете в виду или как это связано с исходным вопросом ... Если под многократным развертыванием вы имеете в виду сопоставление с разными URL-адресами, то да, вы можете это сделать. - person ChssPly76; 28.07.2009

Поскольку вы используете MVC, вы должны предоставить клиенту (т.е. браузеру) доступ к представлению, в данном случае к jsp. Сервлет контроллера следует вызывать из представления, когда над ним выполняется действие. После обработки действия в контроллере вы перенаправляетесь к следующему представлению (которое может быть тем же самым, что инициировало действие).

Сопоставление шаблона URL-адреса сервлета с реальным каталогом приводит к беспорядку, потому что он сообщает контейнеру выбрать сервлет вместо страницы по умолчанию для этого каталога.

person df.    schedule 29.07.2009