Servlets 未调用ServletContextListener
我使用EclipseMaven插件创建了一个JavaEE7项目。我的问题是,当我运行应用程序时,没有调用实现SerlvetContextListener的类。是什么导致了这个问题Servlets 未调用ServletContextListener,servlets,servlet-listeners,Servlets,Servlet Listeners,我使用EclipseMaven插件创建了一个JavaEE7项目。我的问题是,当我运行应用程序时,没有调用实现SerlvetContextListener的类。是什么导致了这个问题 @WebListener public class ApplicationContextListener implements ServletContextListener{ @Override public void contextInitialized(ServletContextEvent sc
@WebListener
public class ApplicationContextListener implements ServletContextListener{
@Override
public void contextInitialized(ServletContextEvent sce)
{
Request request = new HttpRequest(sce);
new Thread (request).start();
HibernateUtil.getSessionFactory();
}
@Override
public void contextDestroyed(ServletContextEvent sce)
{
}
}
web.xml:
com.kyrogaming.AppServletContextListener
泽西servlet
com.sun.jersey.spi.container.servlet.ServletContainer
com.sun.jersey.config.property.packages
com.kyrogaming.webservices
泽西servlet
/服务/*
index.html
在web.xml中,还需要指定
com.kyrogaming.AppServletContextListener
在web.xml中使用metadata complete=“false”修复了这个问题
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1"
metadata-complete="false">
总结JNL和Ted Goddard的答案:
对于要由servlet容器加载的ServletContextListener(或其他侦听器,如ServletContextAttributeListener或ServletRequestAttributeListener),您需要告诉容器有关它的信息。因此,有三种方法可以做到这一点:
metadata complete=“true”
(该属性默认为false
),则不会扫描webapp自己的类(在WEB-INF/classes
下)和库(在WEB-INF/lib
下的JAR)。参见第8.1章“注释和可插拔性”
在web应用程序中,只有当使用注释的类位于web-INF/classes目录中,或者如果它们打包在应用程序中web-INF/lib中的jar文件中,才会对它们的注释进行处理。web应用程序部署描述符在web app元素上包含一个新的“metadata complete”属性。“metadata complete”属性定义web描述符是否完整,或者在部署时是否应检查jar文件的类文件中的注释和web片段。如果“metadata complete”设置为“true”,则部署工具必须忽略应用程序和web片段的类文件中存在的任何servlet注释。如果未指定metadata complete属性或将其设置为“false”,则部署工具必须检查应用程序的类文件中的注释,并扫描web片段
因此,要允许容器在JAR中查找带注释的类,请确保web.xml设置了metadata complete=“false”
,或者根本不设置它
请注意,设置此选项可能会延迟应用程序启动;例如,见
不幸的是,这仍然不能解释为什么问题中的ServletContextListener没有加载。请注意,问题中的web.xml没有
元数据完成
,这意味着它默认为false
,因此启用了类路径扫描。可能还有其他一些问题;希望这个清单有助于找到它。为了记录在案,我添加了另一个导致ServletContextListener
未被调用的可能原因(而且相当恶性)
当您有java.lang.LinkageError
时,即忘记将提供的添加到javax.servlet api
依赖项时,可能会发生这种情况。
在这种情况下,将创建侦听器实例,但只执行静态部分,而不执行contextInitialized
和contextdestromed
方法
只有在调用某个servlet时才能发现,因为在侦听器实例化期间不会引发链接错误。正在运行的容器可能需要显式允许扫描注释:
码头交货价:
cd [JETTY_BASE]
java -jar [JETTY_HOME]/start.jar --add-module=annotations
还有一种极为罕见的情况会导致这种情况。(我花了4个小时才揭开)
如果您使用的是Tomcat10,那么就不能在maven/gradle中使用javax.servlet
库
Tomcat9仍然有javax.servlet
,但Tomcat10迁移到jakarta.servlet
Tomcat10希望有一个使用jakarta.servlet.ServletContextListener
所以使用这个maven依赖项:(提供了作用域,因为Tomcat10已经有了这样的库)
jakarta.servlet
jakarta.servlet-api
5.0.0
假如
这是不真实的。由于JavaEE6,您可以使用@WebListener
注册它们,而不需要任何web.xml
条目。请及时跟进,JavaEE6已经在2009年12月发布了。这也适用于错误地将这个错误答案投上高分的人。根据目前提供的信息,这个问题不可回答。如果我猜的话,那么该侦听器实际上从未在运行时类路径中结束。
cd [JETTY_BASE]
java -jar [JETTY_HOME]/start.jar --add-module=annotations
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>5.0.0</version>
<scope>provided</scope>
</dependency>