使用BlobstoreService App Engine上传GWT表单

时间:2010-06-14 17:07:18

标签: google-app-engine gwt

我正在为我的应用程序使用GWT和Google App Engine Java。我有个人资料屏幕 用户输入姓名,年龄和地址等个人资料信息,保存并获取成功或失败消息。我使用GWT-RPC开发了这个初始应用程序,它运行良好。我有一个新的要求,我必须存储用户的图像。我正在使用BlobstoreService来存储图像。这造成了流程的复杂化。我不得不使用FormPanel,因为它是在GWT中执行FileUpload的唯一方法。 BlobStore服务servlet需要完成重定向。因此,一旦保存配置文件,它现在无法将任何状态返回到我的GWT应用程序。是否可以使用GWT和其他表单字段轻松存储图像,并在保存配置文件后向用户显示状态消息。

4 个答案:

答案 0 :(得分:3)

直到昨天我在Ikai Lan's blog的帮助下找到了解决方案,我一直在努力解决这个问题。基本上,我所做的就是按照他的步骤进行一些修改,因为完全按照他的方式去做,对我来说不起作用:

  1. 创建表单面板:设置编码multipart,方法发布。
  2. 创建一个只有一个方法的GWT远程服务:public String getUploadURL()或类似的东西,在IMPL中写下这个:

    BlobstoreService service = BlobstoreServiceFactory.getBlobstoreService();
    return service.createUploadUrl("/XXX/YYY");
    
  3. 在XXX中你必须放置你的项目路径,例如我的是com.fer.pyn.PictureYourNews

  4. 在YYY中,你必须为我们必须创建的新servlet设置servlet映射名称:我放了XXX = BlobUploader,我创建了一个BlobUploader扩展HttpServlet,你必须更新web.xml。
  5. Okey,所以这是我无法弄清楚的奇怪部分,当我们在步骤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:

  6. 您现在需要做的是创建我们在第4步中讨论的YYY servlet。

  7. 在post方法中,这很重要:

    private BlobstoreService blobService = BlobstoreServiceFactory.getBlobstoreService();
    Map<String, BlobKey> blobMap = blobService.getUploadedBlobs(request);
    BlobKey blobKey = blobMap.get(UPLOAD_WIDJET_NAME);
    
  8. UPLOAD_WIDJET_NAME是FileUpload widjet的.setName。

    1. 你正在做的是为你获取一个关键BLob,以便你以后可以参考。
    2. 我们的下一步是将上传的图像显示回GWT图层:

      //In the same post method from step 7
      ImagesService imagesService = ImagesServiceFactory.getImagesService();
      String imageURL = imagesService.getServingUrl(blobKey);
      response.sendRedirect("/XXX/YYY?imgURL="+imageURL);
      
    3. 现在在get方法中:

      String imageUrl = request.getParameter("imgURL");
      response.setHeader("Content-Type", "text/html");
      response.getWriter().println(imageUrl);
      
    4. 我们已经完成了,现在你只需要

    5. 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
      
      
              }
          });
      

答案 1 :(得分:1)

查看upload4gwt哪些地址可以在AppEngine上的GWT中上传。

(披露:我创建了upload4gwt;它尚未成熟,但可能有用)

答案 2 :(得分:0)

我遇到了同样的问题。作为一种解决方法,我正在使用重定向到servlet,该servlet打印状态消息以供客户端解析。 我将密钥的websafe字符串表示传递给该结果servlet。

这有点hackey,我希望有人能得到更好的答案,或解释为什么blobstore servlet必须重定向。

答案 3 :(得分:0)

是的,GWT上传的内容变得更加复杂。

您可以将表单数据和图像保存在单独的RPC中,并在对图像上载的响应中包含状态消息,或者在表单返回时触发第3个RPC以获取所需的任何状态或元数据。