我希望我的会话在给定的时间间隔后超时。在web.xml中,我一直在使用代码:
<session-config>
<session-timeout>20</session-timeout>
</session-config>
其中20是以分钟为单位的超时时间,它可以正常工作。
我想要做的是在我的一个bean中使用这样的代码以编程方式执行它,如下所示:
@ManagedBean(name="login")
@SessionScoped
public class MyLoginBean implements HttpSessionListener, Serializable {
// private variables etc.
HttpServletRequest request;
HttpSession session = request.getSession();
// Constructor
public MyLoginBean() {
session.setMaxInactiveInterval(1200);
}
// The rest of the code
}
这里的超时是1200秒,即20分钟。不幸的是,在打开浏览器查看应用程序时,它失败并显示消息:
com.sun.faces.mgbean.ManagedBeanCreationException: Cant instantiate class: com.csharp.MyLoginBean.
其次是:
java.lang.NullPointerException
我在这里做错了什么?我知道setMaxInactiveInterval()
指的是特定会话,在这种情况下是登录bean,而不是所有内容,这是web.xml
文件中的代码所指定的内容。我有几个bean,但是登出bean的时机是唯一重要的。
我正在使用JSF 2.0与Glassfish 3.1.1和Eclipse Indigo,因此非常感谢一些建议。
答案 0 :(得分:4)
NullPointerException
有一个非常简单的原因。这是最简单的例外之一。要了解任意异常的原因,请查看其javadoc。所有Java异常都在javadoc中解释了它们的原因。这是javadoc of NullPointerException
的摘录:
当应用程序在需要对象的情况下尝试使用null时抛出。其中包括:
- 调用
null
对象的实例方法。- 访问或修改
null
对象的字段。- 将
null
的长度视为数组。- 访问或修改
null
的插槽,就好像它是一个阵列一样。- 抛出
null
,好像它是一个Throwable值。应用程序应抛出此类的实例以指示其他非法使用null对象。
您的问题是由第1点引起的。
HttpServletRequest request;
HttpSession session = request.getSession();
您尝试在getSession()
而不是具体的null
实例上调用HttpServletRequest
方法。实际上,您应该通过HttpServletRequest
获取ExternalContext#getRequest()
并将其分配给request
。
但是,您遇到了更大的问题:您绝对不应该将当前的servlet请求作为会话范围bean(它的生命周期超过HTTP请求!)的属性。您应该在线程局部范围内(即完全在构造函数或方法块内)获取它。您也不应该让您的JSF托管bean实现HttpSessionListener
。这没有任何意义。您最终会得到2个实例,一个由容器创建为侦听器,另一个由JSF创建为托管bean。
就这样应该这样做:
@ManagedBean(name="login")
@SessionScoped
public class MyLoginBean implements Serializable {
public MyLoginBean() {
HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession();
session.setMaxInactiveInterval(1200);
}
// ...
}
或者,如果您使用的是JSF 2.1,请使用ExternalContext
提供的那个:
FacesContext.getCurrentInstance().getExternalContext().setSessionMaxInactiveInterval(1200);