Сервлет: пересылать запрос сервлету по его имени при использовании аннотаций вместо 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);
Другие вопросы по тегам