Как я могу сопоставить "корневой" сервлет, чтобы другие скрипты все еще выполнялись?
Я пытаюсь создать сервлет, который вызывает JSP-страницу, похожую на следующее:
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException, ServletException {
req.getRequestDispatcher("/WEB-INF/main.jsp").forward(req, resp);
}
Мне нужен этот сервлет для ответа на корень домена (например: http://example.com/), поэтому я использую следующее сопоставление в Интернете .xml:
<servlet-mapping>
<servlet-name>MainServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
Проблема, с которой я сталкиваюсь, заключается в том, что она соответствует всем, поэтому, когда диспетчер пересылает "/WEB-INF/main.jsp", это соответствует шаблону url, поэтому Servlet снова запускается. Это приводит к циклу, который выполняется до тех пор, пока он не умрет с java.lang.StackOverflowError.
Как я могу сопоставить корень, не препятствуя выполнению других сценариев?
Ответы
Ответ 1
Используйте пустой шаблон, например
<servlet-mapping>
<servlet-name>MainServlet</servlet-name>
<url-pattern></url-pattern>
</servlet-mapping>
Спецификация сервлета 3.0 уточнила это:
Пустая строка ("") - это специальный шаблон URL, который точно соответствует корневой контекст приложения
Поэтому он должен хотя бы работать с контейнером 3.0, и я проверил, что он работает на Jetty 8
Ответ 2
Использование элемента приветствующего файла 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>
Ответ 3
В исходном вопросе не упоминается, что они пытаются сопоставить корневой сервлет в App Engine - это легко на Tomcat (и других контейнерах сервлетов, насколько я знаю), но App Engine не является обычным контейнером сервлета.
Мой обычный способ создания веб-приложения с сервлетами заключается в расширении HttpServlet, добавлении объекта "страницы" с заголовком, контентом, ошибками, сообщениями и т.д. и для вывода вперед в шаблон JSP. Это был абсолютный кошмар, работающий в App Engine.
- JSP файлы не могут быть "названы" без "/" в начале.
- Файлы JSP не могут находиться в подкаталоге
- Сервлеты не могут быть сопоставлены с корнем вашего приложения с помощью шаблона url//
Вот мой 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
Вы можете создать файл приветствия с именем index.jsp в корневом каталоге, используя следующий код, используя JSTL или иначе.
<c:redirect url="/main"/>
Итак, в файле web.xml у вас будет следующее:
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
Таким образом, любой пользователь, запрашивающий root, будет перенаправлен в /main. Теперь ваш сервлет можно сопоставить с основным.
<servlet-mapping>
<servlet-name>MainServlet</servlet-name>
<url-pattern>/main</url-pattern>
</servlet-mapping>
Ответ 5
Попробуйте просто удалить '*' из шаблона, т.е.
<url-pattern>/</url-pattern>
Ответ 6
Вы не можете перенаправить на WEB-INF. Контейнер сервлета никогда не будет обслуживать запросы на документы в этой папке.
Если вы хотите, чтобы ваше приложение (а не только сервлет, но все приложение) было доступно в корневом контексте ( "/" из http://www.domainname.com/ "), вам нужно настроить для него контекстную запись - не отображение сервлетов.
С Tomcat вы добавляете новое <Context>
mapping (в одном из трех разных возможных мест).
Ответ 7
Вы пробовали это ниже? (Обратите внимание на отсутствующий *
, который является wild card и является причиной того, что ваша конфигурация ловит все.)
<servlet-mapping>
<servlet-name>MainServlet</servlet-name>
<url-pattern>/index.jsp</url-pattern>
</servlet-mapping>
(Отредактировано в соответствии с комментариями только от /
.)
Ответ 8
Решение упоминается в другой цепочке URL URL для сопоставления сервлета в web.xml, используя URLrewrite → http://tuckey.org/urlrewrite/