Вопрос по servlets, initialization – ServletContainerInitializer против ServletContextListener

37

Я пытаюсь зарегистрировать сервлет, используя servletContainerInitializer, но он, похоже, не работает. Может быть, это мой код (просмотрите его), но я удивился разнице междуServletContainerInitializer а такжеServletContextListenerпотому что следующий код работает нормально при использовании в качествеServletContextListener вместо.

Из спецификации сервлета 3.0:

4.4 Configuration methods (adding servlets dynamically):

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

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 examples & quot; только имя класса отредактировано & quot; также не работает!

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();
        }
    }
}
нет, это также не показывалось Ismail Marmoush
@RameshPVK нет, на самом деле я его не настраивал, можете ли вы сказать мне, как это сделать? или указать мне ссылку? Ismail Marmoush
Итак, вы видели System.out.println (& quot; привет!); печатные Ramesh PVK
Ваш ContainerInitializer загружается? Вы настраивали ContainerInitialzier? Ramesh PVK
Добавил ответ, пожалуйста, проверьте. Ramesh PVK

Ваш Ответ

2   ответа
5

Check if you have configured the ServletContainerInitializer propertly, Имя класса ServletContainerInitializer должно быть настроено внутри файла:

Файл должен содержать только имя класса. Для Ex в вашем случае это должно выглядеть так:

com.marmoush.javaexamples.nullhaus.servlet.MyInit

Файл () может быть упакован в библиотеку JAR в WEB-INF / lib.

Вот любойпример что объясняет.

META-INF / services / javax.servlet.ServletContainerInitializer должен находиться внутри библиотеки, связанной с WEB-INF / lib
со мной не работает, структура моих папок: / javaexamples / Webcontent / META-INF и / javaexamples / src / com / marmoush ... поэтому я создал папку служб, как вы сказали в META-INF, но не сделал Я пошел по ссылке, которую вы сказали, и обнаружил, что META-INF работает параллельно с & quot; com & quot; поэтому я создал другую папку META-INF @ / javaexamples / src / META-INF и не работал Ismail Marmoush
44

ServletContainerInitializer реализация предназначена для объединения в файл JAR, который в свою очередь отбрасывается в/WEB-INF/lib веб-приложения. Сам JAR-файл должен иметь/META-INF/services/javax.servlet.ServletContainerInitializer файл, содержащий FQNServletContainerInitializer реализация в банке. Обратите внимание, что этот файл не должен быть размещен в самом веб-приложении!

Это позволяет разработчикам модулей веб-приложений подключать свои файлы JAR к циклу запуска и завершения работы веб-приложения. Это правда, что они могли бы также использоватьServletContextListener с@WebListener для этого, но это не будет работать, если собственное веб-приложениеweb.xml файл имеетmetadata-complete="true" атрибут установлен в<web-app> это означает, что веб-приложение не должно сканировать JAR-файлы для аннотаций (что экономит время запуска).

ЧтоServletContainerInitializer не работает вyour particular case это может означать только то, что вы на самом деле не разрабатываете файл JAR модуля, а только часть, неотъемлемую часть вашего собственного веб-приложения. В этом случаеServletContainerInitializer являетсяuseless для вас, и вы должны использовать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.
    }

}
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?
Добро пожаловать. Это та же концепция, что и в драйверах JDBC 4.0. Такой драйвер может автоматически регистрироваться без необходимостиClass#forName() если есть/META-INF/services/java.sql.Driver файл в файле JAR драйвера JDBC. Смотрите такжеdocs.oracle.com/javase/7/docs/api/java/sql/DriverManager.html
@ landal79: нет, определенно нет. Библиотека EAR служит совершенно иным целям, не связанным с WAR. Библиотеки, связанные с WAR, абсолютно не должны входить в EAR lib, а в собственные WAR/WEB-INF/lib.
большое спасибо, я не мог заметить servletContainerInitializer & quot; только для упакованных jar-файлов & quot; вещь Ismail Marmoush
По крайней мере, с Apache Tomcat 8.0.32,ServletContainerInitializers могут быть зарегистрированы для веб-приложения вместо его JAR-файлов, еслиMETA-INF/services/javax.servlet.ServletContainerInitializer создано. Также важно помнить, чтоServletContainerInitializers во время начальной загрузки доServletContextListeners, так что если вам нужен ваш код для загрузки перед данной третьей сторонойServletContainerInitializer в комплекте JAR, кажется, единственный вариант для реализацииServletContainerInitializer как часть веб-приложения.
ЛиServletContainerInitializer работать также для jar в папке ear lib?

Похожие вопросы