App Engine Blobstore and Vaadin

Hello,

I’m trying to upload via the Google App Engine Blobstore API some data.

http://code.google.com/appengine/docs/java/blobstore/overview.html#Uploading_a_Blob

Im got in stuck while


public void doPost(HttpServletRequest req, HttpServletResponse res)
        throws ServletException, IOException {

        Map<String, BlobKey> blobs = blobstoreService.getUploadedBlobs(req);
        BlobKey blobKey = blobs.get("myFile");

....

}

how can I cet a HttpServletRequest? or where do I have to create this method?
actually, I use FileUploader, to upload a file and I want to store the Blob when the upload succeeded in:


upload.addListener(new Upload.SucceededListener() {
       public void uploadSucceeded(SucceededEvent event) {
                 // store data
       }
}

Before I tried it with a normal Blob (api.datastore.blob) via JPA but the Blob field doesn’t go saved (all other fields did).
By the way, is there still the 1mb limit on api.datastore.blob (the normal blobs) on App Engine, I’m not sure. I found some old posts

Any thoughts/help?

Thanks, Patrick

Hi Patrick!

I cannot help you with the Google App Engine specifics, sorry. But to get a
HttpServletRequest
you can implement a
TransactionListener
in your application (
Application.getContext().addTransactionListener(…)
).
TransactionListener.transactionStart()
has a parameter called
transactionData
, which can safely be cast to a
HttpServletRequest
.

HTH,
/Jonatan

After taking a quick look at how the Blobstore API works (blobs are not even accessible to the application, can only be uploaded and downloaded by users; …), it would seem to me that the easiest solution would be to use the two example servlets Google provides as-is, mapped to paths outside the path of the Vaadin application in web.xml .

Alternatively, this could be done by subclassing GAEApplicationServlet and overriding the service(HttpServletRequest, HttpServletResponse) method to process requests for certain paths differently, but this might get somewhat more complicated - see also HttpServlet.service(HttpServletRequest, HttpServletResponse) for some extra logic that might be necessary for GET request caching if you want to try this approach.

The Blobstore is one of the most challenging aspects of the Google App Engine. This is the best tutorial I have found for using it:

http://www.fishbonecloud.com/2010/12/tutorial-gwt-application-for-storing.html

I’m currently also trying to implement upload to the AppEngine Blobstore in Vaadin. I went the route mentioned above because this is definitely the easiest.

I do have one problem: I need to associate the upload with the user in that is using the Vaadin application (in the Application User object). How do I go about that?

  • Can I access the user via the http session? I can see there’s some Vaadin key in there, but have no idea how to continue?
  • I’m also thinking about generating a random secret and sending that to the upload form. I’m not sure how safe that is though

Disclaimer: I have not used the Blobstore and very little GAE overall, and I have not tested these techniques.

To access the Vaadin application context and through it the list of open applications for a session, see how it is done in GAEApplicationServlet.getApplicationContext(). Note that the current implementation is considered Vaadin internal code and may change in the future.

I believe the upload URLs are one-time URLs so if nothing else works, you could keep a map somewhere (semi-persistent) from upload URL to the user when creating an upload URL in your application and copy the record to some persistent storage when an upload is actually performed, in the upload handling servlet. This might be unnecessarily complicated, though.

Iam currently stuck in using blobstore with vaadin. First of all the Upload component of vaadin wont work on GAE as GAE doesnt support fileinput and fileoutput stream.

Blobstore depends on the requests and response of the upload so my idea was to override handleupload in the communicationmanager of the application.

The main problem now that i cant get the ApplicationServlet instance of the running application so i can create my own manager and put it in the Map. Is there a way to get this instance of ApplicationServlet ?

Thanks in advance

Hi Henri,

Thanks for the response and tips.

The getApplicationContext looked interesting, but I decided not to go that route. As you say, this is internal to Vaadin and I’d like to be able to upgrade Vaadin without breaking stuff in the future.

Sadly, the upload URL also doesn’t help because you can’t get this back in the handling servlet (the referer is set to the previous url).

If any one wants to do this too: In the end I went with a randomly generated key in the upload form. I store it with the user data and have an index on it. In the upload servlet I associate the “blobkey” with the user via this random secret.

Just let me know if you like a better explanation.

Hello Peter,
Can you please explain more what did you do?. I would be grateful if u provided an example too :slight_smile:

I’ll try to create a standalone example later on, but it really wasn’t that hard.

When a user wants to upload I go through the following:

  1. Create a random upload key that I associate with the user in the datastore
  2. add this to the upload form as a hidden field (I just put the Google provided form in a Label, no nice integration with the other Vaadin components)
  3. In the upload servlet (taken again from the Google docs), I can now get the upload key from the form, search the user and associate the new blobkey with him

If you haven’t yet, I would suggest that you get the Google example working (http://code.google.com/intl/nl/appengine/docs/java/blobstore/overview.html) What I did was only a small variation on that.

I’ve also created Resource that I can embed in a Vaadin application that takes a blobkey as argument and shows the image (see attachement)

One thing I still need to do: In the upload servlet I redirect to the application. This application should refresh so it can display the uploaded image. I’ve added a url parameter “?refresh” that will get caught by a ParameterHandler. I’m not sure if this is the best way to deal with the refresh, but it works.

Hope this helps
11617.java (2.26 KB)

I’ve created an example project and have done a longer write-up on my blog.
It goes in a little more detail of how I did the integration.

You can find the article right here:
http://www.streamhead.com/vaadin-blobstore/

I am not 100% sure that it would work.

Write File to Blobstore
But I follow the instruction over here .and implement a OutputStream which write data to a newly created blob file. Then, it can be used by Upload component of Vaadin.

I have tested my theory in local development server of app engine, but not on real server yet.:*)

Hi Cheng!

Could you please post an example ?