@WebServlet аннотация с Tomcat 7

В моем приложении у меня был сервлет, который был определен следующим образом в файле web.xml:

<servlet>
    <display-name>Notification Servlet</display-name>
    <servlet-name>NotificationServlet</servlet-name>
    <servlet-class>com.XXX.servlet.NotificationServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>NotificationServlet</servlet-name>
    <url-pattern>/notification/*</url-pattern>
</servlet-mapping>

После перехода на использование Tomcat 7 я хотел бы использовать @WebServlet аннотация, которая сделает работу.
Вот как я это сделал:

@WebServlet( name="NotificationServlet", displayName="Notification Servlet", urlPatterns = {"/notification"}, loadOnStartup=1)
public class NotificationServlet extends HttpServlet {

И это не работает. Может кто-нибудь сказать мне, что я сделал не так?

3 ответа

Решение

Если вы уверены, что используете Tomcat 7 или новее, веб-приложение web.xml должен быть объявлен в соответствии со спецификацией Servlet 3.0, чтобы Tomcat мог сканировать и обрабатывать аннотации. В противном случае Tomcat по-прежнему будет работать в резервном режиме, соответствующем версии сервлета в web.xml, Поддержка аннотаций API сервлетов была добавлена ​​только в Servlet 3.0 (Tomcat 7).

Итак, корневая декларация вашего web.xml должен выглядеть как показано ниже (убедитесь, что вы удалили все DOCTYPE от web.xml тоже, иначе он все равно будет интерпретироваться как Servlet 2.3!).

<web-app 
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">

Кроме того, есть небольшая разница в шаблоне URL. Шаблон URL /notifications позволит сервлету прослушивать только запросы именно по этому пути. Он не реагирует на запросы с дополнительным путем, таким как /notifications/list или что-то. Шаблон URL /notifications/* также позволит сервлету прослушивать запросы с дополнительной информацией о пути.

Минимум @WebServlet таким образом, аннотация должна выглядеть так

@WebServlet("/notifications/*")

Остальные атрибуты являются необязательными и, следовательно, не являются обязательными, чтобы сервлет функционировал одинаково.

Смотрите также:

Можно также проверить наличие двух классов с аннотациями с одинаковым именем:

@WebServlet(name = "Foo", urlPatterns = {"/foo"})
public class Foo extends HttpServlet {
    //...
}

А также:

@WebServlet(name = "Foo", urlPatterns = {"/bar"})
public class Bar extends HttpServlet {
    //...
}

В этом случае один из сервлетов не будет работать. Если вы не используете имя, оставьте его, как подсказывает @BalusC. Я получил странное поведение, что один из сервлетов работал только сразу после изменения и компиляции, но не после компиляции без изменений.

Кроме того, чтобы использовать эти аннотации и скомпилировать ваш код, вы должны импортировать соответствующую зависимость в ваш pom.xml, но, как указано, причина, что ваш сервер, совместимый с Servlet 3.0, уже имеет это.

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.0.1</version>
    <scope>provided</scope>
</dependency>
Другие вопросы по тегам