java.lang.IllegalStateException: ServletConfig 尚未初始化
java.lang.IllegalStateException: ServletConfig has not been initialized
我正在尝试创建一个允许用户自定义会话超时的 UI 组件。所以我创建了一个 servlet,如下所示:
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.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
。那么为什么我的配置和上下文设置不正确?
Servlet 早于托管 bean 和注释以及您在 Java EE 6 后看到的所有花哨的东西。以前,您必须显式实现预定义的 abstract/template 方法才能在生命周期中的某个时刻。
对于 servlet,为了像在 "normal" 托管 bean 上使用 @PostConstruct
一样挂接其初始化,您必须覆盖预定义的 GenericServlet#init()
方法。
@Override
public void init() {
// ...
}
getServletContext()
将在那里可用。
如果您注意 GenericServlet
javadoc,您会注意到还有一个 init(ServletConfig)
。但是,强烈建议 不要 使用该方法,而应使用 init()
。 init(ServletConfig)
的默认实现即注意正确设置 ServletContext
。您必须介意调用 super.init(config)
以免犯同样的错误。作为历史记录,请参阅您在托管 bean 上看到的 @PostConstruct
方法的规范名称 "init" 正是继承自此 Servlet API.
如果您想知道,@PreDestroy
等同于 GenericServlet#destroy()
方法。
@Override
public void destroy() {
// ...
}
我正在尝试创建一个允许用户自定义会话超时的 UI 组件。所以我创建了一个 servlet,如下所示:
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.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
。那么为什么我的配置和上下文设置不正确?
Servlet 早于托管 bean 和注释以及您在 Java EE 6 后看到的所有花哨的东西。以前,您必须显式实现预定义的 abstract/template 方法才能在生命周期中的某个时刻。
对于 servlet,为了像在 "normal" 托管 bean 上使用 @PostConstruct
一样挂接其初始化,您必须覆盖预定义的 GenericServlet#init()
方法。
@Override
public void init() {
// ...
}
getServletContext()
将在那里可用。
如果您注意 GenericServlet
javadoc,您会注意到还有一个 init(ServletConfig)
。但是,强烈建议 不要 使用该方法,而应使用 init()
。 init(ServletConfig)
的默认实现即注意正确设置 ServletContext
。您必须介意调用 super.init(config)
以免犯同样的错误。作为历史记录,请参阅您在托管 bean 上看到的 @PostConstruct
方法的规范名称 "init" 正是继承自此 Servlet API.
如果您想知道,@PreDestroy
等同于 GenericServlet#destroy()
方法。
@Override
public void destroy() {
// ...
}