【问题标题】:@WebServlet annotation with Tomcat 7Tomcat 7 的 @WebServlet 注释
【发布时间】:2011-09-26 00:19:15
【问题描述】:

在我的应用程序中,我有一个 servlet,它在 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 {

而且它不起作用。 谁能告诉我我做错了什么?

【问题讨论】:

  • 因为这个问题,我能够摆脱 so much 样板 XML。注释万岁!

标签: servlets annotations tomcat7 servlet-3.0


【解决方案1】:

如果您确定您使用的是 Tomcat 7 或更高版本,则必须将 webapp 的 web.xml 声明为符合 Servlet 3.0 规范,以便让 Tomcat 扫描和处理注释。否则 Tomcat 仍会以与web.xml 中的 Servlet 版本匹配的回退方式运行。 Servlet API 注解的支持仅在 Servlet 3.0 (Tomcat 7) 中添加。

因此,web.xml 的根声明必须如下所示(确保您也从 web.xml 中删除任何 DOCTYPE,否则它仍将被解释为 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 模式/notifications 将让servlet 只监听该路径上的请求。它不会处理带有 /notifications/list 之类的额外路径的请求。 URL 模式/notifications/* 将允许 servlet 监听带有额外路径信息的请求。

因此,最小的@WebServlet 注释应如下所示

@WebServlet("/notifications/*")

其余属性是可选的,因此对于使 servlet 发挥同等作用并不是强制性的。

另见:

【讨论】:

  • 您可能需要添加&lt;web-app (...) metadata-complete="false"&gt;&lt;/webapp&gt;
  • 在使用@WebServlet注解时,完全不必使用web.xml。它可以在没有web.xml 的情况下工作。
  • @destan:没错。但是,如果你有一个,就像在 OP 的情况下一样,它必须至少是 3.0。您最终需要一个,因为并非所有内容都可以注释。
  • @Aniket:所以你说Wikipedia 上的信息比Oracle 自己的Servlet 规范文档中的信息更可靠?为什么?
  • 我有一个奇怪的效果,即 servlet 在刚刚更改、编译并重新部署到 glassfish 4 时工作。当我再次重新编译而没有更改并部署时,它没有工作。我添加了 metadata-complete="false" 属性并最小化了 webservlet-annotation,现在它可以工作了。不过,其他 servlet 一直在工作。
【解决方案2】:

人们可能还想检查两个类是否具有同名的注释:

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

还有:

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

在这种情况下,其中一个 servlet 将不起作用。如果您不使用该名称,请忽略它,就像@BalusC 建议的那样。我得到了一个奇怪的行为,即其中一个 servlet 仅在更改和编译后才可以正常工作,但在没有更改的情况下编译后无法正常工作。

【讨论】:

  • 如果您投反对票,请发表评论,否则任何人都无法回复、纠正或从中学习。谢谢。
【解决方案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>

【讨论】:

    猜你喜欢
    • 2014-07-28
    • 1970-01-01
    • 2021-03-15
    • 2011-11-13
    • 1970-01-01
    • 2012-06-04
    • 2017-02-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多