19

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

    }

}

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>
</web-app>
4

6 に答える 6

29

JNL と Ted Goddard の回答を要約すると、次のようになります。

ServletContextListener (または ServletContextAttributeListener や ServletRequestAttributeListener などの他のリスナー) をサーブレット コンテナーによってロードするには、そのことをコンテナーに伝える必要があります。API ドキュメント で説明されているように、これを行うには 3 つの方法があります。

  1. デプロイメント記述子 (web.xml) で宣言します。

    com.kyrogaming.AppServletContextListener
  2. またはそのクラスに注釈を付けます@WebListener(以下の「注釈に関する注意」を参照)

  3. またはaddListener()などの ServletContext のメソッドを介してプログラムで登録します。

注釈に関する注意

方法 1) と 3) は常に機能します。方法 2) (注釈) が機能するには、クラスパス内のクラスをスキャンして、注釈付きのリスナー クラスを見つけるようにサーブレット コンテナーを構成する必要があります。

web.xml に 属性が含まれている場合(属性のデフォルトは) 、webapp の独自のクラス ( の下WEB-INF/classes) とライブラリ ( の下の JAR WEB-INF/lib) はスキャンされませんmetadata-complete="true"falseJava Servlet Specification Version 3.0の第 8.1 章「注釈とプラグ可能性」を参照してください。

Web アプリケーションでは、アノテーションを使用するクラスは、それらが WEB-INF/classes ディレクトリにある場合、またはアプリケーション内の WEB-INF/lib にある jar ファイルにパッケージ化されている場合にのみ、アノテーションが処理されます。Web アプリケーションのデプロイメント記述子には、web-app 要素に新しい「metadata-complete」属性が含まれています。「metadata-complete」属性は、Web ディスクリプタが完全かどうか、またはデプロイ時に jar ファイルのクラス ファイルのアノテーションと Web フラグメントを検査する必要があるかどうかを定義します。「metadata-complete」が「true」に設定されている場合、デプロイメント ツールは、アプリケーションおよび Web フラグメントのクラス ファイルに存在するサーブレット アノテーションを無視する必要があります。metadata-complete 属性が指定されていないか、「false」に設定されている場合、

したがって、コンテナーが JAR 内のアノテーション付きクラスを検出できるようにするには、web.xml でmetadata-complete="false"が設定されているか、まったく設定されていないことを確認してください。

これを設定すると、アプリケーションの起動が遅くなる可能性があることに注意してください。たとえば、metadata-complete="true" を設定した後に注釈をどうするか (Tomcat 7 の起動が遅い問題を解決しました) を参照してください。.


残念ながら、問題の ServletContextListener がロードされていない理由はまだ説明されていません。問題の web.xml は ではないことに注意してください。つまり、metadata-completeデフォルトで に設定されているためfalse、クラスパスのスキャンが有効になっています。他に問題がある可能性があります。このチェックリストがそれを見つけるのに役立つことを願っています。

于 2016-04-12T08:26:34.767 に答える