我想在JSP页面中重置会话而不会使其失效。
原因是,用户可能已经使用会话打开了一个页面并使其无效会抛出NullPointerException
。由于已经有了新的会话,我不想添加额外的口号。目标是清除所有属性。
我正在寻找类似的东西:
session = new HttpSession(); //this does obviously not work
另一种选择是(?)
while(session.getAttributeNames().hasMoreElements()){
session.removeAttribute(session.getAttributeNames().nextElement());
} //cleans session?
但我不确定,如果删除一些必要的会话属性,如login-data。
有一个很好的方法吗?
编辑最佳解决方案是,每次打开某个页面时,都会为该窗口/选项卡创建一个新会话,直到您关闭该选项卡或在此选项卡中重新访问该页面。这个问题是通过尝试解决this problem.
来实现的答案 0 :(得分:4)
是的,这是一个很好的方法。创建一个包装HttpSession
对象并实现Map
接口的类。在实现中,您可以操作会话属性而不会使会话失效。类似于Struts2框架中SessionMap
的实现代码。您可以在此处阅读SessionMap
的文档页面。
用于处理集合的
Map
接口的简单实现 HTTP会话属性。entrySet()
方法枚举所有 会话属性并创建Set
个条目。请注意,这将发生 懒惰 - 只有在要求输入集时才会使用。
您可以在JSF中找到SessionMap的类似实现。您可以找到文档页面here。
public class SessionMap extends java.util.AbstractMap<java.lang.String,V>
参见:
javax.faces.context.ExternalContext#getSessionMap()
如果你使用这些框架中的任何一个,你可以使用或覆盖clear()
方法来获得你想要的东西。
答案 1 :(得分:3)
HttpSession API显然没有提供此类功能。
使用Java5迭代器习惯用法可以更好地编写上面的循环:
for (final String an : session.getAttributeNames()) {
session.removeAttribute(an);
}
但这需要Enumeration to be iterable。
我想知道的是:您想要清除所有会话数据,但仍保留会话以便其他一些似乎正在使用会话的控件运行不会崩溃。这真的有用吗?第二次控制运行将找不到任何会话数据,因为您已完全清除会话。
我相信其中一个是真的:
HttpSession文档明确指出,使用会话的任何实体必须能够处理会话丢失或从未存在过的事实,因此无论如何都应该实现第2点。
在可扩展性的意义上(如果你的会话中有来自其他进程的数据会发生什么?你的循环也会清除它们)我建议不要清除整个会话,而是跟踪你的控件放置的会话值 - 运行并清除那些显式值。
答案 2 :(得分:1)
你可以像我们在会话中设置值一样使用这个技巧
session.setAttribute( "name", "value");
而不是重置整个会话对象,只需将一些空值设置为会话参数,使其为null,session
对象不会抛出NullPointerException。
例如
session.setAttribute( "name", "");