【问题标题】:GWT form upload using BlobstoreService App Engine使用 BlobstoreService App Engine 上传 GWT 表单
【发布时间】:2010-06-14 17:07:18
【问题描述】:
我正在为我的应用程序使用 GWT 和 Google App Engine Java。我有一个个人资料屏幕,其中
用户输入姓名、年龄和地址等个人资料信息,保存并获得成功或失败消息。我使用 GWT-RPC 开发了这个初始应用程序,它运行良好。我有一个新要求,我必须存储用户的图像。我正在使用 BlobstoreService 来存储图像。这在流程中造成了复杂性。我不得不使用 FormPanel,因为它是在 GWT 中进行 FileUpload 的唯一方法。 BlobStore 服务 servlet 期望在完成时进行重定向。因此,一旦保存了配置文件,它现在就无法将任何状态返回给我的 GWT 应用程序。是否可以轻松地使用 GWT 以及其他表单字段存储图像,并在保存配置文件后向用户显示状态消息。
【问题讨论】:
标签:
google-app-engine
gwt
【解决方案1】:
直到昨天我在Ikai Lan's blog 的帮助下找到了解决方案。基本上我所做的就是按照他的步骤进行,但做了一些修改,因为完全按照他的做法去做这对我来说不起作用:
- 创建表单面板:设置编码多部分,方法发布。
-
创建一个只有一种方法的 GWT 远程服务:public String getUploadURL() 或类似的方法,并在 IMPL 中写下:
BlobstoreService service = BlobstoreServiceFactory.getBlobstoreService();
return service.createUploadUrl("/XXX/YYY");
在 XXX 中你必须输入你的项目路径,例如我的是 com.fer.pyn.PictureYourNews
- 在 YYY 中,您必须为我们必须创建的新 servlet 输入 servlet 映射名称:我输入 XXX = BlobUploader,我创建了一个 BlobUploader 扩展 HttpServlet,您必须更新 web.xml。
-
好吧,这是我想不通的奇怪部分,事情是当我们从第 2 步对远程服务中的 getUploadURL() 进行 RPC 调用时,它会返回一个奇怪的地址,例如:'/_ah /img/eq871HJL_bYxhWQbTeYYoA' 这就是您必须从第一步开始输入表单的 .fromAction。您每次都需要更新表单的操作,所以我建议如下:
public void initBlobStoreSession()
{
imageService.getBlobStoreUploadURL(new AsyncCallback()
{
@Override
public void onSuccess(String result) {
uploadFormPanel.setAction(result);
System.out.println("Upload Form Panel Action set");
}
@Override
public void onFailure(Throwable caught) {
//oops
}
});
}
因此,当您提交 fromPanel 时,它会上传 BLOB,而您无需执行任何操作,棘手的部分是如何获取该 blob:
您现在需要做的是创建我们在第 4 步中讨论的 YYY servlet。
-
在post方法中,这很重要:
private BlobstoreService blobService = BlobstoreServiceFactory.getBlobstoreService();
Map<String, BlobKey> blobMap = blobService.getUploadedBlobs(request);
BlobKey blobKey = blobMap.get(UPLOAD_WIDJET_NAME);
UPLOAD_WIDJET_NAME 是 FileUpload widjet 的 .setName。
- 您正在做的是为您的 Blob 获取一个密钥,以便您以后可以引用它。
-
我们的下一步是将上传的图像显示回 GWT 层:
//In the same post method from step 7
ImagesService imagesService = ImagesServiceFactory.getImagesService();
String imageURL = imagesService.getServingUrl(blobKey);
response.sendRedirect("/XXX/YYY?imgURL="+imageURL);
-
现在在 get 方法中:
String imageUrl = request.getParameter("imgURL");
response.setHeader("Content-Type", "text/html");
response.getWriter().println(imageUrl);
我们已经完成了,现在你只需要
uploadFormPanel.addSubmitCompleteHandler(new SubmitCompleteHandler() {
@Override
public void onSubmitComplete(SubmitCompleteEvent event) {
uploadFormPanel.reset();
initBlobStoreSession();
String imageUrl = event.getResults();
Image image = new Image();
image.setUrl(imageUrl);
//if you are using jetty, leave this on
//or else it wont work
//Don't use GWT.getModuleBaseURL(), it doesnt
//work well in development mode
imageUrl.replace("http://0.0.0.0:8888/", "");
System.out.println(imageUrl);
final PopupPanel imagePopup = new PopupPanel(true);
imagePopup.setWidget(image);
// Add some effects
imagePopup.setAnimationEnabled(true); // animate opening the image
imagePopup.setGlassEnabled(true); // darken everything under the image
imagePopup.setAutoHideEnabled(true); // close image when the user clicks
imagePopup.center(); // center the image
}
});
【解决方案2】:
查看upload4gwt在 AppEngine 的 GWT 中上传的地址。
(披露:我创建了upload4gwt;它还不成熟,但可能有用)
【解决方案3】:
我遇到了同样的问题。作为一种解决方法,我使用重定向到打印状态消息供客户端解析的 servlet。
我正在将密钥的 websafe 字符串表示形式传递给该结果 servlet。
这有点骇人听闻,我希望有人能提供更好的答案,或者解释为什么 blobstore servlet 必须重定向。
【解决方案4】:
是的,在 GWT 中上传会让事情变得更加复杂。
您可以将表单数据和图像保存在单独的 RPC 中,并在对图像上传的响应中包含状态消息,或者在表单返回时触发第三个 RPC 以获得您需要的任何状态或元数据。