Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I submit a text field in the POST request that uploads a blob to the Blobstore and retrieve it in the upload handler for the blob?

I have read several similar questions on StackOverflow but haven't found a solution to this problem yet.

I am uploading a blob from Android to App Engine's Blobstore through an HTTPPost to the upload URL generated by the Blobstore service. I want to be able to send some textual metadata with this request that identifies this blob. I want to retrieve this information along with the blob key in the upload handler servlet that is called after the blob is uploaded.

The problem is that the blob is uploaded using multipart encoding and App Engine does not support the Servlet v3.0 standard, so I can't use req.getPart() to get the textual part. (The blob itself is returned by the Blobstore service, so that part of the request is already parsed for us.)

How can I get around this problem by passing just one text parameter along with the file that is uploaded to the Blobstore and retrieve it in the servlet that is called after the upload of the blob?

Thanks so much for your help! Quite stuck on this one!

Here is the code that I use for HttpPost on Android:

        File file = new File(filePath);
        MultipartEntityBuilder entityBuilder = MultipartEntityBuilder
                .create();
        entityBuilder.addBinaryBody("file", file);           
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(blobUploadURL);
        httpPost.setEntity(entityBuilder.build());
        try {
            HttpResponse response = httpClient.execute(httpPost);
            statusCode = response.getStatusLine().getStatusCode();
        }

UPDATE (Dec 8, '14):

I added a text-body to the entity builder before building the multipart-entity for the HttpPost request as follows:

        String param="value";
        entityBuilder.addTextBody("param", param);

For the servlet that handles the Blobstore's callback after the blob has uploaded, I used the method described by Google to parse an HttpPost request on App Engine in this tutorial as given below:

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {  

    String paramNames="default";

    try {
        ServletFileUpload upload=new ServletFileUpload();
        FileItemIterator iterator=upload.getItemIterator(req);
        while(iterator.hasNext()){
            FileItemStream item=iterator.next();
            InputStream stream=item.openStream();
            if(item.isFormField()){
                paramNames+=item.getFieldName() + ", ";
            }
        }
    } catch (FileUploadException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        paramNames="error";
    }

    //save the paramNames variable in the Datastore for debugging later
    saveParamNamesInDatastore(paramNames);
}

However, when I check the paramNames variable in the datastore after this operation, its value remains "default". That means no form field was found in the rewritten POST request that Blobstore passed to the upload handler servlet. Where to go from here??

like image 856
Price Avatar asked Dec 07 '14 06:12

Price


1 Answers

There's a way to post meta data with your blob with the information that would not be represented by a blobkey:

  1. In your upload form, include this:

    method="post" enctype="multipart/form-data"
    
  2. Now you can either add hidden fields:

    <input type="hidden" name="myName" value="<%= myName %>"/>
    
  3. Or you can add input fields:

    <input type="text" name="myText" size="50" value="Enter your text"/>
    
  4. In your servlet, make sure the post handler reads the meta-data

    String userName = req.getParameter("myName");
    
  5. Now you have the Upload form with all the information.

  6. When you are passing the information to serve the blob, you can use

    &blobkey=daffedafdfe&myName=Blah
    

So, you are not exactly storing the information in the blob itself, but you can include it in the upload form.

like image 117
Ying Li Avatar answered Sep 21 '22 12:09

Ying Li