Как мне сопоставить «корневой» сервлет, чтобы другие сценарии оставались работоспособными? - PullRequest
53 голосов
/ 23 июня 2009

Я пытаюсь создать сервлет, который вызывает страницу JSP, похожую на следующую:

public void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws IOException, ServletException {
    req.getRequestDispatcher("/WEB-INF/main.jsp").forward(req, resp);
}

Мне нужен этот сервлет для ответа на корень домена (например: http://example.com/), поэтому я использую следующее сопоставление в файле web.xml:

<servlet-mapping>
    <servlet-name>MainServlet</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

Проблема, с которой я столкнулся, заключается в том, что это соответствует ВСЕМУ, поэтому, когда диспетчер пересылает в «/WEB-INF/main.jsp», это соответствует шаблону url, поэтому сервлет снова запускается. Это приводит к циклу, который выполняется до тех пор, пока он не умрет с java.lang.StackOverflowError .

Как мне сопоставить корень, не мешая запуску других скриптов?

Ответы [ 8 ]

46 голосов
/ 29 февраля 2012

Используйте пустой шаблон, например,

<servlet-mapping>
    <servlet-name>MainServlet</servlet-name>
    <url-pattern></url-pattern>
</servlet-mapping>

Спецификация сервлета 3.0 прояснила это:

Пустая строка ("") - это специальный шаблон URL, который точно соответствует корень контекста приложения

Так что он должен по крайней мере работать с контейнером 3.0, и я убедился, что он работает на Jetty 8

29 голосов
/ 14 декабря 2010

Использование элемента welcome-file файла web.xml сработало для меня, на движке приложения . Вот мой:

<web-app>
    <servlet>
        <servlet-name>RootServlet</servlet-name>
        <servlet-class>com.foo.RootServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>RootServlet</servlet-name>
        <url-pattern>/foo</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>foo</welcome-file>
    </welcome-file-list>
</web-app>
7 голосов
/ 10 сентября 2009

В первоначальном вопросе не упоминается, что они пытаются отобразить корневой сервлет в App Engine - это легко для Tomcat (и, насколько я знаю, для других контейнеров сервлетов), но App Engine не является обычным контейнером сервлета.

Мой обычный способ создания веб-приложения с сервлетами - это расширение HttpServlet, добавление объекта «page» с заголовком, содержимым, ошибками, сообщениями и т. Д. И для вывода вперед в шаблон JSP. Это стало абсолютным кошмаром для работы в App Engine.

  • Файлы JSP не могут быть названы без "/" в начале.
  • Файлы JSP не могут находиться в подкаталоге
  • Сервлеты не могут быть сопоставлены с корнем вашего приложения с помощью "/" url-pattern

Вот мой web.xml (отредактированный для краткости), который наконец заработал.

<web-app>
  <servlet>
    <!-- this servlet needs to redirect to a NamedDispatcher
         called "template" -->
    <servlet-name>Home</servlet-name>
    <servlet-class>my.domain.HomeSv</servlet-class>
  </servlet>
  <servlet>
    <!-- jsp file must apparently be in root directory and have "/" at
         start of path -->
    <servlet-name>template</servlet-name>
    <jsp-file>/template.jsp</jsp-file>
  </servlet>
  <servlet-mapping>
    <!-- map your home servlet to somewhere other than "/" -->
    <servlet-name>Home</servlet-name>
    <url-pattern>/home</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <!-- make your Home servlet the welcome file -->
    <welcome-file>home</welcome-file>
  </welcome-file-list>
</web-app>

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

4 голосов
/ 23 июня 2009

Вы можете создать файл приветствия с именем index.jsp в корне со следующим кодом, используя JSTL или иным образом.

<c:redirect url="/main"/>

Итак, в файле web.xml у вас будет это:

<welcome-file-list>
    <welcome-file>index.jsp</welcome-file>        
</welcome-file-list>

Таким образом, любой, кто запрашивает рут, будет перенаправлен на / main. Теперь ваш сервлет может быть привязан к основному.

<servlet-mapping>
    <servlet-name>MainServlet</servlet-name>
    <url-pattern>/main</url-pattern>
</servlet-mapping>
1 голос
/ 20 августа 2009

Решение упоминается в другом потоке Шаблон URL для отображения сервлета в web.xml с использованием URLrewrite -> http://tuckey.org/urlrewrite/

1 голос
/ 23 июня 2009

Попробуйте просто удалить '*' из шаблона, т.е.

<url-pattern>/</url-pattern>
0 голосов
/ 23 июня 2009

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

<servlet-mapping>
        <servlet-name>MainServlet</servlet-name>
        <url-pattern>/index.jsp</url-pattern>
</servlet-mapping>

(отредактировано в соответствии с комментариями от /.)

0 голосов
/ 23 июня 2009

Вы не можете перенаправить на WEB-INF. Контейнер сервлета никогда не будет обслуживать запросы документов в этой папке.

Если вы хотите, чтобы ваше приложение (не просто сервлет, а все приложение) было доступно в корневом контексте ("/" из "http://www.domainname.com/"),), вам необходимо настроить контекстную запись для него не отображение сервлета.

С Tomcat вы добавляете новое <Context> отображение (в одном из примерно 3-х возможных мест).

...