java.lang.IllegalStateException: ServletConfig не был инициализирован

Я пытаюсь создать компонент пользовательского интерфейса, который позволяет пользователю настроить время ожидания сеансов. Итак, я создал сервлет, как показано ниже:

public class SessionTimeoutServlet extends AbstractBaseServlet {
    private static final long serialVersionUID = 2567293974465204729L;

    public static final String REQUEST_TIMEOUT_PARAMETR_NAME = "timeout";
    private static final String TIMEOUT_TYPE_INIT_PARAMETER_NAME = "timeoutType";
    private static final String WEB_TYPE_TIMEOUT = "web";
    private static final String WEBSERVICE_TYPE_TIMEOUT = "webService";

    @EJB(mappedName = SessionSettingsRemote.BEAN_NAME)
    private SessionSettingsRemote sessionSettingsBean;

    @PostConstruct
    public void initTimeout() {
        try {
            String timeoutType = getServletContext().getInitParameter(TIMEOUT_TYPE_INIT_PARAMETER_NAME);
            if (WEBSERVICE_TYPE_TIMEOUT.equals(timeoutType)) {
                setCustomTimeout(sessionSettingsBean.getSessionSettingsDTO().getWebServiceSessionTimeoutInterval());
            } else if (WEB_TYPE_TIMEOUT.equals(timeoutType)) {
                setCustomTimeout(sessionSettingsBean.getSessionSettingsDTO().getWebSessionTimeoutInterval());
            } else {
                setCustomTimeout(30);
            }
        } catch (ApplicationException e) {
            setCustomTimeout(30);
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        int timeout = Integer.parseInt(request.getParameter(REQUEST_TIMEOUT_PARAMETR_NAME));
        setCustomTimeout(timeout);
    }

    public static void setCustomTimeout(int customTimeout) {
        SessionManagerListener.setCustomTimeout(customTimeout);
    }

}

Однако, когда я развертываю это на GlassFish, я получаю исключение ниже.

Caused by: java.lang.IllegalStateException: ServletConfig has not been initialized
    at javax.servlet.GenericServlet.getServletContext(GenericServlet.java:199)
    at com.accedian.ems.uiapplication.server.servlets.SessionTimeoutServlet.initTimeout(SessionTimeoutServlet.java:33)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl$3.run(InjectionManagerImpl.java:766)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.invokeLifecycleMethod(InjectionManagerImpl.java:760)
    at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.inject(InjectionManagerImpl.java:531)
    at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.injectInstance(InjectionManagerImpl.java:141)
    at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.injectInstance(InjectionManagerImpl.java:127)
    at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.createManagedObject(InjectionManagerImpl.java:347)
    at com.sun.enterprise.web.WebContainer.createServletInstance(WebContainer.java:991)
    at com.sun.enterprise.web.WebModule.createServletInstance(WebModule.java:2130)
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1404)
    at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1381)
    at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5732)

я использовал getServletConfig() до getServletContext() но это было null, Так почему мой конфиг и контекст не установлены должным образом?

1 ответ

Решение

Сервлеты предшествуют управляемым bean-компонентам, аннотациям и всем причудливым материалам, которые вы видите после Java EE 6. Ранее вам нужно было явно реализовать предопределенный метод абстракции / шаблона, чтобы выполнить задачу в определенный момент жизненного цикла.

Для сервлетов, чтобы подключить его инициализацию так же, как вы использовали бы @PostConstruct на "обычном" управляемом бине вы должны переопределить предопределенный GenericServlet#init() метод.

@Override
public void init() {
    // ...
}

getServletContext() будет доступно там.

Если вы обратите внимание на GenericServlet Javadoc, вы заметите, что есть также init(ServletConfig), Однако настоятельно рекомендуется не использовать этот метод, а использовать init() вместо. Реализация по умолчанию init(ServletConfig) а именно заботится о том, чтобы ServletContext правильно установлено. Вы должны были бы возражать super.init(config) не совершать ту же ошибку. Как историческое примечание, увидеть, что каноническое имя @PostConstruct Метод, как вы видите на управляемых компонентах, "init", унаследован именно от этого API сервлета.

Если вам интересно, то @PreDestroy эквивалент GenericServlet#destroy() метод.

@Override
public void destroy() {
    // ...
}
Другие вопросы по тегам