2016-03-22 2 views
1

Я пытаюсь создать компонент пользовательского интерфейса, который позволяет пользователю настраивать время ожидания сеансов. Поэтому я создал сервлет, как показано ниже: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. Итак, почему моя конфигурация и контекст не установлены правильно?

+0

Не используйте вместо этого '@ PostConstruct' вместо метода init. Это будет вызвано слишком рано на жизненном цикле (после построения, но до того, как в контейнере произойдут какие-либо изменения в вызове 'init (ServletConfig)', поэтому все по-прежнему «null». –

ответ

2

Servlets predate управляемые бобы и аннотации и все фантазии, которые вы видите с Java EE 6. Раньше вы должны явно реализовать предопределенный метод abstract/template для выполнения задачи в определенный момент жизненного цикла.

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

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

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

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

В случае, если вы задаетесь вопросом, эквивалент @PreDestroy - это метод GenericServlet#destroy().

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