views:

4001

answers:

4

Hi, I am looking for the simplest way to upload and store an image (file) to the GAE (java). Googling for hours without any simple and clear result... : (

found this link: http://code.google.com/intl/fr/appengine/kb/java.html#fileforms

but i still don't know how to store an image, and how to retrieve it... I am looking for simple servlet exmample...

+23  A: 

The link your provided How do I handle file uploads to my app? explains how you can upload the image.

To host the images, you need to use the Datastore service to store and serve image along with your other data.

Here is a sample code. It is meant as a sketch, for how you can have your own entity (i.g. business, user, etc) have a field for an image. I ignored all error handling and recovery to simplify the code.

Declaring your entity with the image. You can imagine having other fields, e.g. tags, location, etc

@Entity
public class MyImage {
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Long id;

    @Persistent
    private String name;

    @Persistent
    Blob image;

    public MyImage() { }
    public MyImage(String name, Blob image) {
        this.name = name; 
        this.image = image;
    }

    // JPA getters and setters and empty contructor
    // ...
    public Blob getImage()              { return image; }
    public void setImage(Blob image)    { this.image = image; }
}

Then when you start accepting images (watch out for cases where an image with the same name has already been uploaded in addition to the typical file upload failures). ServletFileUpload and IOUtils are classes that are part of the Apache Commons library.

// Your upload handle would look like
public void doPost(HttpServletRequest req, HttpServletResponse res) {
    // Get the image representation
    ServletFileUpload upload = new ServletFileUpload();
    FileItemIterator iter = upload.getItemIterator(req);
    FileItemStream imageItm = iter.next();
    InputStream imgStream = imageItem.openStream();

    // construct our entity objects
    Blob imageBlob = new Blob(IOUtils.toByteArray(imgStream));
    MyImage myImage = new MyImage(image.getName(), imageBlob);

    // persist image
    PersistenceManager pm = PMF.get().getPersistenceManager();
    pm.makePersistent(myImage);
    pm.close();

    // respond to query
    res.setContentType("text/plain");
    res.getOutputStream().write("OK!".getBytes());
}

And finally when you want to serve an image given its name:

Blob imageFor(String name, HttpServletResponse res) {
    // find desired image
    PersistenceManager pm = PMF.get().getPersistenceManager();
    Query query = pm.newQuery("select from MyImage " +
        "where name = nameParam " +
        "parameters String nameParam");
    List<MyImage> results = (List<MyImage>)query.execute(name);
    Blob image = results.next().getImage();

    // serve the first image
    res.setContentType("image/jpeg");
    res.getOutputStream().write(image.getBytes());
}
notnoop
thank you very much for this clear and comprensible answer !!! : )
OXMO456
wonderful, thank you. can you tell me why byte array will not give proper output, although its getting stored etc., I had posed this question a while ago http://stackoverflow.com/questions/2018597/cannot-fetch-image-data-in-gwt-google-datastore-image-is-strected-out
dhaval
excellent answer!
maclema
A: 

OK, exactly as in sample MediaStore, but what to do if you want to prepare (resize/rotate) before saving?

Evgenii
A: 

How to deal with the time out? If the image upload/download may exceed 30 sec.

Should I rather use the Blob Store Service (if it handles the time out issue automatically)?

e.g. (from Google)

<form action="<%= blobstoreService.createUploadUrl("/upload") %>" 
method="post" enctype="multipart/form-data">

public void doPost(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException {
    Map<String, BlobKey> blobs = blobstoreService.getUploadedBlobs(req);
    BlobKey blobKey = blobs.get("myFile");
    ...
}


public void doGet(HttpServletRequest req, HttpServletResponse res)
throws IOException {
    BlobKey blobKey = new BlobKey(req.getParameter("blob-key"));
    blobstoreService.serve(blobKey, res);
}
Yoichi
+2  A: 

Use the blobstore API: http://code.google.com/appengine/docs/java/blobstore/overview.html

Claude Vedovini