【问题标题】:GAE: Way to get reference to an HttpSession from its ID?GAE:如何从其 ID 中获取对 HttpSession 的引用?
【发布时间】:2016-02-17 01:59:32
【问题描述】:

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

但是,我可以存储getId() 返回的 ID。根据this question 的说法,出于安全原因,从其 ID 获取会话的能力已被贬低,但 GAE 实现有所不同。根据this blog post,您可以使用ID 来获取代表HttpSession 的DataStore 实体,但我想要对Java 对象的引用,而不是用于在JVM 之间迁移它的底层数据。

那么,有什么方法可以做我想做的事吗?

【问题讨论】:

  • 好的,所以我必须将您的问题阅读三遍左右才能了解您要完成的工作。但是,我仍然看不到您所要求的实际用途。如果您使用#setAttribute(name, obj)FooBar 对象存储在HttpSession 中,则可以随时从会话中获取该对象(在该会话中)。当您总是通过其父 HttpSession 引用 FooBar 对象时,为什么要创建循环引用?当您没有会话对象时,您应该无法访问与其关联的任何数据。那么为什么要破坏会话安全呢?

标签: java google-app-engine servlets httpsession


【解决方案1】:

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");

我是凭记忆写代码的,所以请先在生产环境中测试一下,然后加上cast check之类的标准东西,但大体思路是一样的。

【讨论】:

猜你喜欢
  • 2010-11-18
  • 2017-10-13
  • 2011-12-17
  • 1970-01-01
  • 2017-07-02
  • 2016-09-24
  • 2011-11-30
  • 2011-01-05
  • 1970-01-01
相关资源
最近更新 更多