Search code examples
javagoogle-app-engineimage-uploading

How to upload and store an image with google app engine (java)


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.

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


Solution

  • 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 imageItem = iter.next();
        InputStream imgStream = imageItem.openStream();
    
        // construct our entity objects
        Blob imageBlob = new Blob(IOUtils.toByteArray(imgStream));
        MyImage myImage = new MyImage(imageItem.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.iterator().next().getImage();
    
        // serve the first image
        res.setContentType("image/jpeg");
        res.getOutputStream().write(image.getBytes());
    }