Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ServletContainerInitializer vs ServletContextListener

I'm trying to register a servlet using servletContainerInitializer but it doesn't seem to work, Maybe it's my code (kindly review it), but I came to wonder about the difference between ServletContainerInitializer and ServletContextListener, because the follwing code runs fine when used as ServletContextListener instead.

From servlet 3.0 specification:

4.4

Configuration methods (adding servlets dynamically):

... or from the onStartup method of a ServletContainerInitializer implementation ...

The 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/*");     } } 

The servlet which I'm trying to auto-register:

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");     } } 

Original code from nullhaus java examples website "only class name edited" also didn't work!

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();         }     } } 
like image 931
Ismail Marmoush Avatar asked May 27 '12 19:05

Ismail Marmoush


People also ask

What is Servletcontextlistener in Java?

void contextInitialized(ServletContextEvent sce) Receives notification that the web application initialization process is starting. All ServletContextListeners are notified of context initialization before any filters or servlets in the web application are initialized.

Which annotation would you use to declare an array of application classes to be passed to a ServletContainerInitializer in Java?

You know, the @HandlesTypes annotation is used to annotate a class that implements javax. servlet. ServletContainerInitializer interface. It declares the class types in which an implementation of ServletContainerInitializer is interested.


1 Answers

The ServletContainerInitializer implementation is intented to be bundled in a JAR file which is in turn been dropped in /WEB-INF/lib of the webapp. The JAR file itself should have a /META-INF/services/javax.servlet.ServletContainerInitializer file containing the FQN of the ServletContainerInitializer implementation in the JAR. Please note that this file should thus not be placed in the webapp itself!

This allows webapp module developers to let their JAR file hook on webapp's startup and shutdown cycle. It's true that they could also have used a ServletContextListener with @WebListener for this, but this won't work if the webapp's own web.xml file has a metadata-complete="true" attribute set in <web-app> which means that the webapp shouldn't scan JARs for annotations (which saves startup time).

That the ServletContainerInitializer doesn't work in your particular case can only mean that you're actually not developing a module JAR file, but just a part integral to your own web application. In that case, the ServletContainerInitializer is useless for you and you should be using ServletContextListener instead.

@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.     }  } 

See also:

  • Map servlet programmatically instead of using web.xml or annotations
  • Splitting up shared code and web.xml from WAR project to common JAR project
  • Using special auto start servlet to initialize on startup and share application data
  • what is the equivalence of contextDestroyed() in ServletContainerInitializer?
like image 167
BalusC Avatar answered Sep 28 '22 20:09

BalusC