ServletContainerInitializer

ServletContainerInitializer

本文介绍了ServletContainerInitializer与ServletContextListener的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用servletContainerInitializer注册一个servlet,但它似乎不起作用,也许是我的代码(请仔细检查它),但是我想知道 ServletContainerInitializer ServletContextListener ,因为当用作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.

根据Servlet 3.0规范:

From servlet 3.0 specification:

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

我要自动注册的servlet:

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

nullhaus Java示例网站的原始代码仅编辑类名";也没用!

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

推荐答案

ServletContainerInitializer实现旨在捆绑在一个JAR文件中,然后将其放入Webapp的/WEB-INF/lib中. JAR文件本身应具有一个/META-INF/services/javax.servlet.ServletContainerInitializer文件,其中应包含JAR中ServletContainerInitializer实现的FQN.请注意,因此不应将此文件放置在webapp本身中!

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!

这使webapp模块开发人员可以让其JAR文件挂在webapp的启动和关闭周期上.的确,他们也可以将ServletContextListener@WebListener一起使用,但是如果webapp自己的web.xml文件在<web-app>中设置了metadata-complete="true"属性,则此方法将无效,这意味着该webapp应该不会在JAR文件中扫描注释(节省启动时间).

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

ServletContainerInitializer在您的特殊情况下不起作用仅表示您实际上不是在开发模块JAR文件,而只是您自己的Web应用程序不可或缺的一部分.在这种情况下,ServletContainerInitializer对您来说没用,您应该改用ServletContextListener.

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

}

另请参见: