我希望我的会话在给定的时间间隔后超时。在 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
指定的。我有几个豆子,但超时登录豆是唯一重要的。
我将JSF 2.0与Glassfish 3.1.1和Eclipse Indigo一起使用,因此非常感谢一些建议。
NullPointerException
有一个非常简单的原因。这是最简单的例外之一。要了解任意异常的原因,只需查看其javadoc。所有 Java 异常在 javadoc 中都有其原因的解释。以下是 javadoc of NullPointerException
的摘录:
当应用程序尝试在需要对象的情况下使用 null 时引发。其中包括:
- 调用
null
对象的实例方法。- 访问或修改
null
对象的字段。- 将
null
的长度视为数组。- 访问或修改
null
插槽,就好像它是一个数组一样。- 投掷
null
,就好像它是一个可投掷的值一样。应用程序应引发此类的实例,以指示 null 对象的其他非法使用。
您的问题是由第 1 点引起的。这里
HttpServletRequest request;
HttpSession session = request.getSession();
您正在尝试在null
而不是具体的HttpServletRequest
实例上调用getSession()
方法。实际上,您应该通过ExternalContext#getRequest()
获得HttpServletRequest
并将其分配给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);