Ich erstelle ein Java EE 7 Projekt mit dem Eclipse Maven Plugin. Mein Problem ist, wenn ich die Anwendung die Klasse ausführen, die SerlvetContextListener implementiert, wird nicht aufgerufen. Was verursacht dieses Problem?
%Vor%web.xml:
%Vor%
Die Verwendung von metadata-complete="false" in web.xml hat dieses Problem für mich behoben.
%Vor%Um die Antworten von JNL und Ted Goddard zusammenzufassen:
Damit ein ServletContextListener (oder andere Listener, z. B. ServletContextAttributeListener oder ServletRequestAttributeListener) vom Servlet-Container geladen werden, müssen Sie den Container darüber informieren. Als in den API-Dokumenten beschrieben, gibt es drei Möglichkeiten, dies zu tun:
1) Deklarieren Sie es im Deployment-Deskriptor (web.xml):
%Vor% 2) oder kommentieren seine Klasse mit @WebListener
(siehe "Hinweis zu Anmerkungen" unten)
3) oder registrieren es programmatisch über die Methoden in ServletContext, z. B. addListener () .
Hinweis zu Anmerkungen
Methode 1) und 3) werden immer funktionieren. Damit Methode 2) (Annotationen) funktioniert, muss der Servlet-Container so konfiguriert werden, dass er die Klassen im Klassenpfad durchsucht, um die mit Anmerkungen versehenen Listener-Klassen zu finden.
Die eigenen Klassen der Webapps (unter WEB-INF/classes
) werden immer gescannt, daher werden immer kommentierte Klassen gefunden. Bibliotheken (JARs unter WEB-INF/lib
) werden jedoch nicht gescannt, wenn die web.xml das Attribut metadata-complete="true"
enthält (das Attribut ist standardmäßig auf false
gesetzt). Siehe die Java-Servlet-Spezifikation Version 3.0 , Kapitel 8, "Anmerkungen und Pluggability".
Damit der Container annotierte Klassen in JARs findet, stellen Sie sicher, dass web.xml metadata-complete="false"
festlegt oder gar nicht setzt.
Beachten Sie, dass dies möglicherweise den Start der Anwendung verzögert; Siehe zum Beispiel Was mit Annotationen zu tun ist nach dem Setzen von metadata-complete="true" (was den langsamen Start von Tomcat 7 auflöst)? .
Leider erklärt das immer noch nicht, warum der ServletContextListener in der Frage nicht geladen ist. Beachten Sie, dass die web.xml in der Frage nicht metadata-complete
lautet, dh, sie ist standardmäßig auf false
eingestellt. Daher ist die Klassenpfadüberprüfung aktiviert. Es gibt wahrscheinlich ein anderes Problem; Diese Checkliste hilft hoffentlich, sie zu finden.
Zur Erinnerung, ich füge noch eine weitere mögliche (und ziemlich bösartige) Ursache hinzu, dass ServletContextListener
nicht aufgerufen wird.
Dies kann passieren, wenn Sie java.lang.LinkageError
haben, also wenn Sie vergessen haben, <scope>provided</scope>
zu Ihrer javax.servlet-api
Abhängigkeit hinzuzufügen.
In diesem Fall wird die Listener-Instanz erstellt, aber nur der statische Teil wird ausgeführt, nicht die Methoden contextInitialized
und contextDestroyed
.
Sie sollten nur feststellen, wenn Sie ein Servlet aufrufen, da der Verknüpfungsfehler bei der Listener-Instanziierung nicht auftritt.
Tags und Links servlets servlet-listeners