GAE:从ID中引用HttpSession的方法?

时间:2015-11-16 01:58:38

标签: java google-app-engine servlets httpsession

在Google App Engine下,您要存储在HttpSession中的任何对象都必须实现Serializable,并且其所有字段都必须是可序列化的,因为在GAE中运行的实例可能会从一个JVM到另一个。这意味着,如果我想将FooBar个实例存储到HttpSession中,我就不能在其中指向一个字段,指向HttpSession

但是,我可以存储getId()返回的ID。根据{{​​3}},出于安全原因,已从其ID获取会话的能力已被折旧,但GAE实施方式不同。根据{{​​3}},您可以使用ID来获取表示HttpSession的DataStore实体,但我想要引用Java对象,而不是用于在JVM之间迁移它的基础数据。

那么,有什么办法可以做我想要的吗?

1 个答案:

答案 0 :(得分:3)

Relevant paragraph from your link:

  

为每个新创建类型为“_ah_SESSION”的数据存储区实体   HttpSession中。实体键是“_ahs”+ session.getId()。每   _ah_SESSION实体有两个属性“_values”和“_expires”。

     

“_values”属性只是序列化的byte []表示   包含会话数据的HashMap。

所以你可以做的如下:

// When putting FooBar to session
FooBar fooBar;
HttpSession session;
session.setAttribute("fooBar", fooBar);

而另一方面:

// When getting session from datastore
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Key sessionKey = KeyFactory.createKey("_ah_SESSION", sessionId);
Entity sessionEntity = datastore.get(sessionKey);
byte[] sessionBytes = sessionEntity.getProperty("_values");

ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(sessionBytes);
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
Map<?, ?> sessionMap = (Map) objectInputStream.readObject();
FooBar restoredFooBar = (FooBar) sessionMap.get("fooBar");

我是从内存中编写代码的,所以请先在生产中测试一下,然后添加标准内容,比如强化检查,但总体思路是一样的。