Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/magento/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Servlets ServletContainerInitializer与ServletContextListener_Servlets_Initialization - Fatal编程技术网

Servlets ServletContainerInitializer与ServletContextListener

Servlets ServletContainerInitializer与ServletContextListener,servlets,initialization,Servlets,Initialization,我试图使用servletContainerInitializer注册一个servlet,但它似乎不起作用,可能是我的代码(请查看),但我想知道和之间的区别,因为下面的代码在用作ServletContextListener时运行良好 @WebListener public class Config implements ServletContextListener { @Override public void contextInitialized(ServletContextE

我试图使用servletContainerInitializer注册一个servlet,但它似乎不起作用,可能是我的代码(请查看),但我想知道和之间的区别,因为下面的代码在用作
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.
    }

}
来自servlet 3.0规范:

4.4 配置方法(动态添加servlet): 。。。或者从
ServletContainerInitializer
实现的
onStartup
方法


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/*");
    }
}
来自NullhausJava示例网站“仅编辑类名”的原始代码也不起作用

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();
        }
    }
}
package com.marmoush.javaexamples.nullhaus.servlet;
导入java.util.Set;
导入javax.servlet.servlet;
导入javax.servlet.ServletContainerInitializer;
导入javax.servlet.ServletContext;
导入javax.servlet.ServletException;
导入javax.servlet.ServletRegistration;
公共类MyInit实现ServletContainerInitializer{

启动时公共无效(设置检查是否已正确配置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中


下面是一些解释。

ServletContainerInitializer的
ServletContainerInitializer
实现打算捆绑在一个JAR文件中,该文件又被放到webapp的
/WEB-INF/lib
中。JAR文件本身应该有一个
/META-INF/services/javax.servlet.servlet.ServletContainerInitializer
文件,其中包含e
ServletContainerInitializer
JAR中的实现。请注意,此文件因此不应放在webapp本身中

这允许webapp模块开发人员让他们的JAR文件钩住webapp的启动和关闭周期。确实,他们也可以将
ServletContextListener
@WebListener
一起使用,但如果webapp自己的
web.xml
文件具有
元数据complete=“true”,这将不起作用
中设置的属性,这意味着webapp不应该扫描jar中的注释(这节省了启动时间)

ServletContainerInitializer
在您的特定情况下不起作用,这只意味着您实际上没有开发模块JAR文件,而只是您自己的web应用程序的一部分。在这种情况下,
ServletContainerInitializer
对您来说是无用的,您应该使用
ServletCont改为extListener

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

}
另见:

您的ContainerInitializer正在加载吗?您是否配置了ContainerInitializer?@RameshPVK否实际上我没有配置它,您能告诉我如何配置它吗?或者给我指一个链接吗?您看到System.out.println(“你好”)了吗;printed添加答案,请检查。与我无关,我的文件夹结构是:/javaexamples/Webcontent/META-INF和/javaexamples/src/com/marmoush…所以我创建了服务文件夹,正如你在META-INF中所说的,但不起作用,所以我找到了你说的链接,发现他说META-INF与“com”并列文件夹,因此我创建了另一个META-INF@/javaexamples/src/META-INF,但它不起作用。Hermeta-INF/services/javax.servlet.ServletContainerInitializer应该位于绑定在WEB-INF中的库中/lib@IsmailMarmoush您应该检查生成的WAR中的文件夹结构,而不是开发文件夹结构,在那里您应该有
WEB-INF/classes/META-INF/services/javax.servlet.ServletContainerInitializer
,我可以确认它在Apache Tomcat 8.0.32中注册了一个
ServletContainerInitializer
。非常感谢,我似乎没有注意到ServletContainerInitializer“仅用于捆绑的JAR”不客气。这与JDBC 4.0驱动程序中的概念相同。这样的驱动程序可以自动注册,而无需
Class#forName()
如果JDBC驱动程序JAR文件中有
/META-INF/services/java.sql.Driver
文件。请参阅
ServletContainerInitializer
是否也适用于ear lib文件夹中的JAR?@landal79:不,绝对不。ear lib的用途与WAR无关。与WAR相关的库绝对不应该使用o在EAR库中,但在WAR自己的
/WEB-INF/lib
中。至少在Apache Tomcat 8.0.32中,
ServletContainerInitializer
s可以为WEB应用程序注册,而不是它的JAR,只要创建了适当的
META-INF/services/javax.servlet.ServletContainerInitializer
。另一件需要记住的重要事情这是
ServletContainerInitializer
s在
ServletContextListener
s之前的启动加载期间,因此如果您需要在JAR中绑定的给定第三方
ServletContainerInitializer
之前加载代码,那么唯一的选项似乎是将
ServletContainerInitializer
作为web应用程序的一部分实现。