我有一个GWT应用程序,它的后端有RPC服务。我目前正在尝试实现用户支持,唯一仍然存在的问题是我应该存储会话数据的方式。
我正在使用
存储会话IDgetThreadLocalRequest().getSession().setAttribute("sid", "randomSIDgoeshere");
因此,第一个问题更多的是Java servlet而不是GWT。这段代码是否保证下次我这样打电话:
getThreadLocalRequest().getSession().getAttribute("sid");
它将为null(如果为尚未访问过设置了SID属性的代码的用户调用它),或者它与我已为该用户保存的SID完全相同。换句话说,这两个代码是用户特定的吗? (通过 user 我的意思是在一台计算机上使用单个浏览器)
第二个问题是关于存储SID和一些额外数据(如用户ID)之间的映射。如果我有这样的代码:
public class MyGwtServiceImpl extends RemoteServiceServlet implements MyGwtService {
// SID to User ID mappings
private final Map<String, String> sessions =
new HashMap<String, String>();
...
}
是否保证sessions
始终是所有请求的同一对象,并且除非整个应用程序终止,否则其数据将保持“活动”状态? (例如停止Tomcat)这是正常的方法还是我应该在我的数据库上保留所有这些映射?
答案 0 :(得分:7)
首先:
是的,确实有保证。下次在下一个请求中调用getThreadLocalRequest().getSession().getAttribute("sid");
时,属性sid将保留在那里。但请记住,这是本地请求区域,因此只有来自同一用户(浏览器+ ip)的请求才能共享信息。这意味着:
事实:
案例1
案例2
案例3
是的,会话的内容是特定于用户的。一个会话中存在的内容并不意味着在其他会话中存在。
第二
不,不保证。虽然大多数时候会调用相同的servlet isntance,但不能保证它始终存在。如果要在servlet中保留属性,则必须将这些属性声明为静态,因此,静态属性不会是特定于用户的。或者您可以存储在ServeletContext
中我这样说是因为不同的实现(如Glassfish)可以终止实例,如果长时间不需要服务器(据我记得,我不确定这个(Glassfish)终止实例))。但是没有文档说它确实保证将是同一个实例,因此你不能声明非静态属性并在不同的实例之间共享。