我可以一次性将图片保存到 Blobstore 并将数据保存到 Datastore 吗?
Can I save images to Blobstore and save data to Datastore in one trip?
这个论点已经在很多场合提出并得到解决:Blobstore 在存储图像方面比 DataStore 更好。现在假设我有一个类似于 Instagram 或 Facebook 或 Yelp 或任何图像密集型应用程序的应用程序。在我的特殊情况下,理想模型是
public class IdealPostModel{
Integer userId;
String synopsys;
Blob image;
...//more data/fields about the post
}
但由于我必须使用 BlobStore,我的模型没有 blob,而是 URL 或 BlobKey。重要的是要发送一个 post(即保存一个 post 到服务器)应用程序必须——按照这个顺序——
- 将所有非 blob 数据发送到服务器。
- 等待服务器响应
BlobstoreUtils.generateServingUrl(null)
数据
- 将图像发送到 BlobStore
- 让 BlobStore 使用图像的 BlobKey 或 url 向我的服务器发送响应
- 将 BlobKey/url 存储在我的 DataStore 实体中
握手次数太多了!!!
有没有办法将第一步中的所有数据发送到服务器:字符串和图像。然后让服务器从那里做其他一切?当然,我在这里希望减少工作量。我想 App Engine 现在应该已经很成熟了,一定有比我的架构更简单的方法。
现在我当然会在这里,因为我遇到了数据已保存但 BlobKey 或 URL 未保存到实体的情况。大约有 10% 的时间会发生这种情况。或者可能更少,但确实感觉像是 10%。它让我的用户发疯,这意味着它让我更加发疯,因为我不想失去我的用户。
理想情况下
- 应用一次调用即可将所有内容发送到服务器:图像和元数据,例如 userId 和 synopsys
- 服务器以某种方式从 Blobstore 获取 blob 密钥
- 服务器将图像发送到 blobstore,存储在提供的 blob 键中,服务器将其他数据发送到 DataStore,还包括数据存储中的 blob 键。
更新
public static String generateServingUrl(String path) {
BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
return blobstoreService.createUploadUrl(null == path ? "/upload" : path);
}
这是我服务器上的一个片段。
工作流程不同。举个例子:
新post的表单下有"Post"按钮和"Attach an image"按钮。
当用户点击“附加”按钮时,您要求用户 select 一个文件并将其保存到 BlobStore(或 Google 云存储)。无需调用 BlobstoreUtils.generateServingUrl(null)
- 您需要上传 URL。当调用 returns 键时,您将其存储在 Post 对象中。
当用户点击 Post 按钮时,您会保存 Post - 包括数据存储中的图像密钥。因此,整个工作流只需要两次调用。
如果用户点击“取消”按钮 - 请记住删除上传的图像(如果有),否则它们将被孤立。棘手的部分是,如果用户只是离开了您的应用程序或失去了连接,就删除这些图像。
如果需要,您可以反向操作 - 先保存 post,然后让用户附加图像。这不是大多数用户所期望的,但它解决了孤立图像的问题。
您实际上可以在一个请求中发送所有内容。
请记住,当您使用通过调用 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¶m2=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 对象。
这个论点已经在很多场合提出并得到解决:Blobstore 在存储图像方面比 DataStore 更好。现在假设我有一个类似于 Instagram 或 Facebook 或 Yelp 或任何图像密集型应用程序的应用程序。在我的特殊情况下,理想模型是
public class IdealPostModel{
Integer userId;
String synopsys;
Blob image;
...//more data/fields about the post
}
但由于我必须使用 BlobStore,我的模型没有 blob,而是 URL 或 BlobKey。重要的是要发送一个 post(即保存一个 post 到服务器)应用程序必须——按照这个顺序——
- 将所有非 blob 数据发送到服务器。
- 等待服务器响应
BlobstoreUtils.generateServingUrl(null)
数据 - 将图像发送到 BlobStore
- 让 BlobStore 使用图像的 BlobKey 或 url 向我的服务器发送响应
- 将 BlobKey/url 存储在我的 DataStore 实体中
握手次数太多了!!!
有没有办法将第一步中的所有数据发送到服务器:字符串和图像。然后让服务器从那里做其他一切?当然,我在这里希望减少工作量。我想 App Engine 现在应该已经很成熟了,一定有比我的架构更简单的方法。
现在我当然会在这里,因为我遇到了数据已保存但 BlobKey 或 URL 未保存到实体的情况。大约有 10% 的时间会发生这种情况。或者可能更少,但确实感觉像是 10%。它让我的用户发疯,这意味着它让我更加发疯,因为我不想失去我的用户。
理想情况下
- 应用一次调用即可将所有内容发送到服务器:图像和元数据,例如 userId 和 synopsys
- 服务器以某种方式从 Blobstore 获取 blob 密钥
- 服务器将图像发送到 blobstore,存储在提供的 blob 键中,服务器将其他数据发送到 DataStore,还包括数据存储中的 blob 键。
更新
public static String generateServingUrl(String path) {
BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
return blobstoreService.createUploadUrl(null == path ? "/upload" : path);
}
这是我服务器上的一个片段。
工作流程不同。举个例子:
新post的表单下有"Post"按钮和"Attach an image"按钮。
当用户点击“附加”按钮时,您要求用户 select 一个文件并将其保存到 BlobStore(或 Google 云存储)。无需调用
BlobstoreUtils.generateServingUrl(null)
- 您需要上传 URL。当调用 returns 键时,您将其存储在 Post 对象中。当用户点击 Post 按钮时,您会保存 Post - 包括数据存储中的图像密钥。因此,整个工作流只需要两次调用。
如果用户点击“取消”按钮 - 请记住删除上传的图像(如果有),否则它们将被孤立。棘手的部分是,如果用户只是离开了您的应用程序或失去了连接,就删除这些图像。
如果需要,您可以反向操作 - 先保存 post,然后让用户附加图像。这不是大多数用户所期望的,但它解决了孤立图像的问题。
您实际上可以在一个请求中发送所有内容。
请记住,当您使用通过调用 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¶m2=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 对象。