【问题标题】:Can I save images to Blobstore and save data to Datastore in one trip?我可以一次将图像保存到 Blobstore 并将数据保存到 Datastore 吗?
【发布时间】:2015-03-23 20:48:33
【问题描述】:

这个论点已经在很多场合提出并解决了:Blobstore 比 DataStore 更适合存储图像。现在假设我有一个类似于 Instagram、Facebook 或 Yelp 的应用程序或任何图像密集型应用程序。在我的特殊情况下,理想的模型是

public class IdealPostModel{

  Integer userId;
  String synopsys;
  Blob image;
  ...//more data/fields about the post

}

但是由于我必须使用 BlobStore,所以我的模型没有 blob,而是一个 URL 或 BlobKey。重要的问题是,要发送帖子(即将帖子保存到服务器),应用程序必须 - 按此顺序 -

  1. 将所有非 blob 数据发送到服务器。
  2. 等待服务器以BlobstoreUtils.generateServingUrl(null) 数据响应
  3. 将图像发送到 BlobStore
  4. 让 BlobStore 使用图像的 BlobKey 或 url 向我的服务器发送响应
  5. 将 BlobKey/url 存储在我的 DataStore 实体中

握手次数太多了!!!

有没有办法在第一步中将所有数据发送到服务器:字符串和图像。然后从那里让服务器做其他所有事情?当然,我在这里希望减少工作量。我认为 App Engine 现在应该已经相当成熟了,而且肯定有比我的架构更简单的方法。

现在我当然在这里,因为我遇到了数据已保存但 BlobKey 或 URL 未保存到实体的情况。它大约有 10% 的时间发生。或者可能更少,但感觉确实像 10%。它让我的用户发疯,这意味着它让我更发疯,因为我不想失去我的用户。

理想

  1. 应用在一次调用中将所有内容发送到服务器:图像和元数据,例如 userId 和 synopsys
  2. 服务器以某种方式从 Blobstore 获取 Blob 密钥
  3. 服务器将图像发送到 blobstore,以存储在提供的 blob 密钥中,服务器将其他数据发送到 DataStore,包括数据存储中的 blob 密钥。

更新

    public static String generateServingUrl(String path) {
        BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
        return blobstoreService.createUploadUrl(null == path ? "/upload" : path);
    }

这是我服务器上的一个 sn-p。

【问题讨论】:

  • 什么是BlobstoreUtils.generateServingUrl(null)?我从来没有听说过。
  • 是否有可能让 BlobStore 回调返回到 android 而不是我的服务器?

标签: java google-app-engine google-cloud-datastore blobstore google-eclipse-plugin


【解决方案1】:

工作流程不同。鉴于你的例子:

  1. 新帖子的表单下方有“发布”按钮和“附加图片”按钮。

  2. 当用户点击“附加”按钮时,您会要求用户选择一个文件并将其保存到 BlobStore(或 Google 云存储)。无需致电BlobstoreUtils.generateServingUrl(null) - 您需要获取上传 URL。当调用返回一个键时,您将它存储在 Post 对象中。

  3. 当用户点击“发布”按钮时,您会保存发布 - 包括数据存储中的图像键(键)。因此,整个工作流程只需要两次调用。

  4. 如果用户点击取消按钮 - 请记住删除上传的图像(如果有),否则它们将被孤立。棘手的部分是如果用户只是离开您的应用或断开连接,则删除这些图像。

如果您愿意,您可以颠倒这个过程 - 先保存帖子,然后让用户附加图片。这不是大多数用户所期望的,但它解决了孤立图像的问题。

【讨论】:

  • 这很有趣。我需要考虑一下。太感谢了。 +1。
  • 您是否有示例说明如何从 android 或 iOS 将图像发送到 BlobStore 并接收 url 作为响应?谢谢。
  • 你这么说The entire workflow takes only two calls。这似乎表明我可以从android获得uploadUrl。那是对的吗?现在我在服务器上这样做:blobstoreService.createUploadUrl(string).
  • 如果您的回复中包含以下步骤,您能帮我澄清一下吗? 1app => server: get upload url; 2app => BlobStore : save my blob; 3BlobStore => server : here is the BlobKey; 4server => app : here is the BlobKey; 5app => server : here is post data associated with blobKey.
  • 我认为此时代码 sn-p 是有序的。我也很难做到这一点。而我只是一个好奇的旁观者。
【解决方案2】:

您实际上可以在一个请求中发送所有内容。

请记住,当您使用通过调用 blobstoreService.createUploadUrl("/yourservingurl") 获得的 URL 发送 blob 时,GAE 实际上会向不同的 URL 发出第一个请求,存储 blob,然后调用 /yourservingurl 传递给您您可以通过以下方式检索的 blobkeys:

Map<String, List<BlobKey>> blobs = blobstoreService.getUploads(req);
List<BlobKey> blobKeys = blobs.get("myFile");

因此,在第一次请求之后,所有其他表单值实际上都会丢失,但是如果您可以动态构建该 URL,例如

blobstoreService.createUploadUrl("/yourservingurl?param1=a&param2=b")

然后您可以在 Servlet 上取回这些参数并一次性持久化所有内容(包括已存储的 blob 的 blobkey),从而减少对数据存储的调用。

更新: 步骤是

1) 收集客户端的所有参数并使用这些参数创建一个上传 URL,例如:blobstoreService.createUploadUrl("/yourservingurl?userId=989787")。 GAE 将为该特定请求生成一个唯一的 URL。

当您提交表单时,GAE 将保留 blob 并调用 /yourservingurl

2) 在服务 /yourservingurl 的 Servlet 上,您将获得您上传的所有 blobkeys 表单文件,方法是:blobstoreService.getUploads(request) AND 您可以获得包含的参数与标准request.getParameter("userId")

3) 现在,在您的 servlet 中,您拥有发送的所有参数(例如 userId)以及 blobkey,您可以在一次调用中持久化您的 Post 对象。

【讨论】:

  • 感谢您的回复,但它太简洁了,我无法理解。您介意以我一直在做的方式详细说明这些步骤吗?所以你是说:第一步:app =&gt; server: here are post and image;第二步:server =&gt; BlobStore: save image with upleadUrl;第三步:server =&gt; datastore: save post entity;第四步:blobStore =&gt; server (callback): here is BlobKey;第 5 步:server =&gt; datastore: add blobKey to post entity。这是你的想法吗?
  • 谢谢我错过了。 +1。这很有帮助。但我还有两个悬而未决的问题。 1)使用这个系统,android(即客户端)不会立即知道数据何时被持久化,因为没有响应:回调转而转到我的服务器,对吗? 2)既然那个get call是我的,我想怎么长就怎么长?因为元数据包括一个可以是很多字符的评论部分。谢谢。
  • 1) 您确实会从您的 servlet/endpoint 表单中获得对客户端的响应,但不是来自 blob 上传本身,这是由 GAE 完成的,并且是完全透明的。您必须在处理 /yourservingurl 的 servlet 上构建响应 2)不幸的是,这是一个 hack,您将被限制为最大 URL 长度(大约 2000 个字符,取决于浏览器) .如果您打算发送更长的文本,则必须再次拨打电话才能发送该文本。
  • 换句话说,您知道 blobstore 是否限制上传 url 中的字符数吗?
  • 不在 blobstore 方面,限制来自 HTTP 协议实现本身。 GAE 有 2048 个字符的限制,但有一个 [请求扩展] (code.google.com/p/googleappengine/issues/detail?id=7053)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-28
  • 1970-01-01
  • 2023-03-22
  • 2013-08-10
  • 1970-01-01
相关资源
最近更新 更多