@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 {

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

Ответ 1

При условии, что вы уверены, что используете Tomcat 7 или новее, webapp web.xml должен быть объявлен соответствующим требованиям Servlet 3.0, чтобы заставить Tomcat сканировать и обрабатывать аннотации. В противном случае Tomcat по-прежнему будет работать в резервном модуле, соответствующем версии Servlet в 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/*")

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

См. также:

Ответ 2

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

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

и

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

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

Ответ 3

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

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.0.1</version>
    <scope>provided</scope>
</dependency>

Ответ 4

Среди многих интересных функций Servlet 3.0 представил аннотации, которые упрощают развертывание сервлетов, фильтров и прослушивателей всех типов. Большинство аннотаций WebServlet упакованы под javax.servlet.annotation

http://j2eereference.com/2015/11/webservlet-annotations/