【发布时间】:2012-07-25 01:14:54
【问题描述】:
我有一个精简的测试项目,其中包含一个 Servlet 3.0 版,使用如下注释声明:
@WebServlet("/test")
public class TestServlet extends HttpServlet {
private static final long serialVersionUID = -3010230838088656008L;
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException{
response.getWriter().write("Test");
response.getWriter().flush();
response.getWriter().close();
}
}
我也有这样的 web.xml 文件:
<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">
<servlet>
<servlet-name>testServlet</servlet-name>
<servlet-class>g1.TestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>testServlet</servlet-name>
<url-pattern>/testWebXml</url-pattern>
</servlet-mapping>
</web-app>
我尝试使用 Embedded Tomcat 7 进行 JUnit 测试。当我启动 Embedded Tomcat 时,我只能通过 web.xml (/testWebXml) 中声明的 url-pattern 访问 servlet。如果我尝试通过注释 (/test) 声明的 url-pattern 访问它,则找不到 404 页面。
这是我的测试代码:
String webappDirLocation = "src/main/webapp/";
Tomcat tomcat = new Tomcat();
tomcat.setPort(8080);
tomcat.addWebapp("/jerseyTest", new File(webappDirLocation).getAbsolutePath());
tomcat.start();
tomcat.getServer().await();
为了确保我正确设置了我的项目,我还安装了一个实际的 Tomcat 7 并部署了战争。这一次,我的 servlet 的 web.xml 声明的 url 和注释 url 都可以正常工作。
所以我的问题是:有谁知道如何让 Embedded Tomcat 7 考虑到我的 Servlet 3.0 注释?
我还应该声明它是一个 Maven 项目,并且 pom.xml 包含以下依赖项:
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
<version>7.0.29</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>7.0.29</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jasper</artifactId>
<version>7.0.29</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
== 更新 ==
这是一个看起来与此类似的问题(除了不起作用的 Servlet 3.0 注释在 Listener 上,而不是 Servlet),它有一个建议的修复:
https://issues.apache.org/bugzilla/show_bug.cgi?id=53903
我试过了,还是不行:
将 Embedded Tomcat 启动代码更改为:
String webappDirLocation = "src/main/webapp/";
Tomcat tomcat = new Tomcat();
tomcat.enableNaming();
tomcat.setPort(8080);
Context ctx = tomcat.addWebapp(tomcat.getHost(), "/embeddedTomcat", new File(webappDirLocation).getAbsolutePath());
((StandardJarScanner) ctx.getJarScanner()).setScanAllDirectories(true);
tomcat.start();
tomcat.getServer().await();
我尝试过的其他事情,也没有成功:
在 web.xml “web-app” 标签中专门设置 metadata-complete="false"
将 Maven 依赖项更新到版本 7.0.30
调试
org.apache.catalina.startup.ContextConfig类。那里有检查@WebServlet注释的代码,只是它永远不会被执行(第2115 行)。这可能是找到问题根源的好方法,但是课程很大,我现在没有时间这样做。也许如果有人愿意看看这个类是如何工作的,以及在什么条件下(配置参数)它可以正确检查你的项目的类的注释,它可能会得到一个有效的答案。
【问题讨论】:
-
我也无法在嵌入式 Tomcat 7 中获得 Servlet 3.0(基于注释的)应用程序。当我下拉到 Servlet 2.5 并将我的 servlet 放入
web.xml时工作正常.我第一次尝试使用嵌入式 Jetty 8 ......但是在将头撞到墙上一整天后,我发现 Servlet 3 注释仅在您使用“hightide”Jetty 变体时可用(我无法开始工作在嵌入式模式下)。 -
嵌入式 Tomcat 文档几乎不存在。 Eclipse 人员为 Jetty 提供了漂亮的文档,但它充满了巨大的空白(例如,什么是“高潮”以及何时使用它,如何嵌入带有 JSP 支持的版本 8 和基于注释的 servlet 配置等)。感觉所有这些东西都缺少一些基本的难题......我不确定现在是否有人正在使用带有任何这些嵌入式 servlet 引擎的 Servlet 3.0。
-
只是对上面 Shivan 示例的注释...问题不在于他将基于注释的配置与基于 web.xml 的配置混合在一起。即使您从 web.xml 中删除了 servlet 和 servlet 映射,注释声明的映射本身仍然不起作用。
-
有趣的是,我已经通过 Maven Jetty 插件获得了在嵌入式 Jetty 8 中运行的基于注释的 Servlet 3.0 应用程序。所以必须有一些可能的途径来完成所有这些工作。但是,这种情况只是在 Maven 构建脚本中运行服务器......这与以编程方式将 Tomcat 或 Jetty 实例嵌入应用程序中并独立发布它不同。
-
“我发现 Servlet 3 注释仅在您使用“hightide”Jetty 变体时可用(我也无法在嵌入式模式下工作)。” - 这不准确,不管目标是不使用码头,那么码头标签应该被删除,它只是在 cmets 中提到
标签: java jakarta-ee tomcat servlets