在 Google App Engine 下,您想要存储在 HttpSession
中的任何对象必须实现 Serialized
,并且其所有字段都必须可序列化,因为在 GAE 中运行的实例可能会从一个 JVM 迁移到另一个 JVM。这意味着,如果我想将 FooBar
实例存储到 HttpSession
中,则其中不能有一个字段指向 HttpSession
。
但是,我可以存储getId()
返回的ID。根据this question出于安全原因,从 ID 获取 session 的能力已被降低,但 GAE 实现有所不同。根据this blog post您可以使用 ID 来获取表示 HttpSession
的 DataStore 实体,但我需要对 Java 对象的引用,而不是用于在 JVM 之间迁移它的底层数据。
那么,有什么办法可以实现我想要的功能吗?
最佳答案
Relevant paragraph from your link:
A Datastore entity of kind "_ah_SESSION" is created for each new HttpSession. The entity key is "_ahs" + session.getId(). Each _ah_SESSION entity has two properties "_values" and "_expires".
The "_values" property is simply the serialized byte[] representation of a HashMap that includes the the session data.
所以你可以做如下:
// 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");
我凭内存编写了代码,因此请先在生产中对其进行测试,并添加标准内容(例如转换检查),但总体思路是相同的。
关于java - GAE : Way to get reference to an HttpSession from its ID?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33727444/