ServletContainerInitializerを使用してサーブレットを登録しようとしていますが、機能していないようです。たぶんそれは私のコードです(親切にレビューします)が、 ServletContainerInitializer
の違いについて疑問に思いました=と ServletContextListener
です。これは、次のコードをServletContextListener
として使用すると正常に実行されるためです。
サーブレット3.0仕様から:
4.4
構成メソッド(サーブレットを動的に追加):
...または
onStartup
実装のServletContainerInitializer
メソッドから...
ServletContainerInitializer
:
package com.marmoush.javaexamples.nullhaus.servlet;
import Java.util.Set;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
public class MyInit implements ServletContainerInitializer {
public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException {
System.out.println("hello");
ServletRegistration reg = ctx.addServlet("q31","com.marmoush.javaexamples.nullhaus.servlet.Q31");
reg.addMapping("/q31/*");
}
}
自動登録しようとしているサーブレット:
package com.marmoush.javaexamples.nullhaus.servlet;
import Java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Q31 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().println("hello world");
}
}
Nullhausの元のコードJavaサンプルWebサイト「クラス名のみ編集」も機能しませんでした!
package com.marmoush.javaexamples.nullhaus.servlet;
import Java.util.Set;
import javax.servlet.Servlet;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
public class MyInit implements ServletContainerInitializer {
public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException {
try {
Class klass = Class.forName("com.marmoush.javaexamples.nullhaus.servlet.Q31");
Class<Q31> clazz = (Class<Q31>) klass;
Servlet s = ctx.createServlet(clazz);
ServletRegistration.Dynamic d = ctx.addServlet("q31", s);
d.addMapping("/baz/*");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
ServletContainerInitializer
の実装は、JARファイルにバンドルされることを意図しており、JARファイルはWebアプリケーションの/WEB-INF/lib
にドロップされます。 JARファイル自体には、JAR内のServletContainerInitializer
実装のFQNを含む/META-INF/services/javax.servlet.ServletContainerInitializer
ファイルが必要です。したがって、このファイルはWebアプリケーション自体に配置しないでください。
これにより、webappモジュールの開発者は、JARファイルをwebappの起動およびシャットダウンサイクルにフックさせることができます。これにはServletContextListener
と@WebListener
を一緒に使用することもできますが、これは、Webアプリケーションのweb.xml
ファイルにmetadata-complete="true"
属性が設定されている場合は機能しません<web-app>
これは、webappが注釈を求めてJARをスキャンしないことを意味します(起動時間を節約します)。
ServletContainerInitializer
が特定のケースで機能しないということは、実際にモジュールJARファイルを開発していないだけで、独自のWebアプリケーション。その場合、ServletContainerInitializer
は役に立たないので、代わりにServletContextListener
を使用する必要があります。
@WebListener
public class Config implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent event) {
// Do stuff during server startup.
}
@Override
public void contextDestroyed(ServletContextEvent event) {
// Do stuff during server shutdown.
}
}
ServletContainerInitializerを適切に構成したかどうかを確認します。 ServletContainerInitializerクラス名は、ファイル内で構成する必要があります。
META-INF/services/javax.servlet.ServletContainerInitializer
ファイルにはクラス名のみが含まれている必要があります。あなたの場合のExの場合は次のようになります:
com.marmoush.javaexamples.nullhaus.servlet.MyInit
ファイル(META-INF/services/javax.servlet.ServletContainerInitializer)は、WEB-INF/libのライブラリJARにバンドルできます。
これは、説明している example です。