Сервлет: пересылать запрос сервлету по его имени при использовании аннотаций вместо web.xml?
У меня есть входной сервлет (называемый DispatcherServlet), который перенаправляет все входящие запросы GET и POST в /* на другие сервлеты в зависимости от параметра конфигурации. Для того, чтобы отправить запрос другим сервлетам, я использую их имя вместо пути, потому что мой DispatcherServlet окажется в бесконечном цикле при прослушивании /*.
"Старый" способ состоял в том, чтобы дать сервлетам имя в дескрипторе web.xml:
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>mypackage.MyServlet</servlet-class>
</servlet>
После этого можно обращаться к сервлету по его имени, например, при использовании RequestDispatcher
, Код в моем DispatcherServlet выглядит следующим образом:
RequestDispatcher dispatcher = getServletContext (). GetNamedDispatcher("MyServlet"); dispatcher.forward(запрос, ответ);
Это работает отлично. Но я хотел бы использовать "новые" аннотации Servlet 3 без web.xml, поэтому я делаю это:
@WebServlet(name="MyServlet")
public class MyServlet extends HttpServlet {
...
Но сейчас, getServletContext().getNamedDispatcher("MyServlet")
в моем DispatcherServlet возвращает ноль вместо соответствующего диспетчера для MyServlet
хотя я ожидаю что @WebServlet(name="MyServlet")
ведет себя так же, как <servlet-name>MyServlet</servlet-name>
Я проверил это на Tomcat 7. Это потому, что MyServlet еще не был загружен к тому времени, когда вызывается DispatcherServlet, и, следовательно, имя MyServlet не известно? Если да, то какой смысл @WebServlet(name="...")
аннотации делают;)
Пожалуйста, не отвечайте что-то вроде "почему вы не используете фильтры?" и т.д. Это больше о фоне аннотаций по сравнению с web.xml
Заранее спасибо!
(ps. пожалуйста, измените название, если вы найдете более подходящий;))
2 ответа
Если вы не укажете urlMapping с именем, вам нужно будет добавить полное имя класса. подобно
RequestDispatcher dispatcher = getServletContext().
getNamedDispatcher("mypackage.MyServlet");
Это работает для меня, если сервлет аннотирован как:
@WebServlet(urlPatterns="/Servlet", name="Servlet")
или лучше:
@WebServlet(urlPatterns="/Servlet", displayName="Servlet", name="Servlet")
Также вы можете попытаться получить имя вашего сервлета с помощью:
getServletName()
Просто прокомментируйте с @WebServlet
недостаточно для загрузки сервлета в веб-контейнер; Вы должны включить хотя бы один шаблон URL-адреса, и если вы не хотите предоставлять сервлет для сохранения его только для внутренней пересылки, установите URL-адрес, начинающийся с '/WEB-INF/'.
И имейте в виду, что свойство 'name' содержит ошибки, поэтому не используйте его.
@WebServlet(urlPatterns = "/WEB-INF/thisServlet")
public class FooServlet extends HttpServlet {
...
}
и чтобы переслать запрос, позвоните примерно так:
servletContext.getNamedDispatcher(FooServlet.class.getName()).forward(request, response);