2016-03-22 130 views
1

ユーザーがセッションのタイムアウトをカスタマイズできるようにするUIコンポーネントを作成しようとしています。そこで、以下のようにサーブレットを作成しました。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) 

私はgetServletContext()getServletConfig()を使用しているが、それはnullでした。では、なぜ私の設定とコンテキストが正しく設定されていないのですか?

+0

代わりに '@ PostConstruct'オーバーライドを使用しないでください。これはライフサイクルの早い段階で呼び出されます(コンストラクション後、コンテナが 'init(ServletConfig) 'を呼び出す前に何も変更されないため、すべてがまだヌルです)。 –

答えて

2

サーブレットは、マネージドBeanとアノテーション、およびJava EE 6以降に見られるすばらしいすべての要素を先取りします。以前は、ライフサイクルの特定の瞬間にタスクを実行するために事前定義済みの抽象/テンプレートメソッドを明示的に実装する必要がありました。

サーブレットの場合、「通常の」マネージドBeanで@PostConstructを使用するのと同じ方法で初期化をフックするには、定義済みのGenericServlet#init()メソッドをオーバーライドする必要があります。

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

getServletContext()が利用可能です。

GenericServlet javadocに注目すると、init(ServletConfig)もあることに気づくでしょう。しかし、ではなく、を使用することを強くお勧めしますが、その代わりにinit()を使用してください。 init(ServletConfig)のデフォルトの実装では、ServletContextが適切に設定されていることに注意してください。 super.init(config)と同じ間違いをしないように気をつけてください。過去のメモとして、マネージドBean "init"に表示されている@PostConstructメソッドの正規名は、このサーブレットAPIから継承されていることを確認してください。

あなたが不思議に思うような場合は、@PreDestroyに相当するのはGenericServlet#destroy()メソッドです。

@Override 
public void destroy() { 
    // ... 
} 
関連する問題