ServletContextListener未被调用

Mar*_*nis 14 servlets servlet-listeners

我使用Eclipse Maven插件创建了一个Java EE 7项目.我的问题是当我运行应用程序时,实现SerlvetContextListener的类不会被调用.是什么导致了这个问题?

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

    }

}
Run Code Online (Sandbox Code Playgroud)

web.xml中:

<?xml version="1.0" encoding="UTF-8"?>
<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">
<listener>com.kyrogaming.AppServletContextListener</listener>
<!-- Jersey Mapping -->
<servlet>
    <servlet-name>jersey-servlet</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>com.sun.jersey.config.property.packages</param-name>
        <param-value>com.kyrogaming.webservices</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>jersey-servlet</servlet-name>
    <url-pattern>/service/*</url-pattern>
</servlet-mapping>
<!-- end Jersey Mapping -->

<welcome-file-list>
    <welcome-file>index.html</welcome-file>
</welcome-file-list>
Run Code Online (Sandbox Code Playgroud)

sle*_*ske 19

总结JNL和Ted Goddard的答案:

对于要由servlet容器加载的ServletContextListener(或其他侦听器,例如ServletContextAttributeListener或ServletRequestAttributeListener),您需要告诉容器它.如API文档中所述,有三种方法可以执行此操作:

1)在部署描述符(web.xml)中声明它:

<listener>
    <listener-class>
        com.kyrogaming.AppServletContextListener
    </listener-class>
</listener>
Run Code Online (Sandbox Code Playgroud)

2)注释其类@WebListener(参见下面的"关于注释的注释")

3)通过ServletContext中的方法(例如addListener())以编程方式注册它.

关于注释的注意事项

方法1)和3)将始终有效.要使方法2)(注释)起作用,必须将servlet容器配置为扫描类路径中的类,以查找带注释的侦听器类.

WEB-INF/classes将始终扫描webapp自己的类(下),因此将始终找到带注释的类.但是,如果web.xml包含属性(属性默认为),则不会扫描库(JAR下WEB-INF/libmetadata-complete="true"false).请参阅Java Servlet规范3.0版,第8章"注释和可插拔性".

因此,要允许容器在JAR中查找带注释的类,请确保web.xml设置metadata-complete="false"或根本不设置它.

请注意,设置此项可能会延迟应用程序启动; 例如,参见设置metadata-complete ="true"(解决了Tomcat 7启动缓慢)后如何处理注释?.


不幸的是,这仍然无法解释为什么未加载问题中的ServletContextListener.请注意,问题中的web.xml没有metadata-complete,这意味着它是默认的false,因此启用了类路径扫描.可能还有其他一些问题; 这份清单有望帮助找到它.


小智 13

在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">
Run Code Online (Sandbox Code Playgroud)


JNL*_*JNL 6

在web.xml中,您还需要指定<listener-class>

    <listener>
        <listener-class>
                 com.kyrogaming.AppServletContextListener
        </listener-class>
    </listener>
Run Code Online (Sandbox Code Playgroud)

  • 这是不正确的。从Java EE 6开始,您可以使用@WebListener来注册它们,而无需任何web.xml条目。请及时赶上,Java EE 6自2009年12月以来已经退出市场。这也适用于错误地认为该错误答案的人。 (23认同)
  • 根据目前提供的信息,问题无法回答。如果我猜到了,那么该侦听器根本不会真正落在运行时类路径中。 (2认同)