1

I currently have the following problem:

I would like to upload a Blob to the Google Blobstore from my client Java application. In the Blobstore documentation (https://cloud.google.com/appengine/docs/java/blobstore/) is described how to do this with a form with which the Blob is uploaded by using a FileChooser.

However, I would like to do this from my code, but I do not know how to convert the Object to a Blob in Java. I would like to pass the generated Blob in a HttpURLConnection, and I have created the classes for this on the Google App Engine.

So my question is: how can I upload a Blob from a client java application?

Note: in my case I would like to upload a JavaFX Image as a Blob, but I think this question could be asked in general.

UPDATE 1: Using the FileService could be the solution, as @TejjD kindly pointed out. However, the Files API is going to be deprecated and is therefore not useful.

UPDATE 2: I am using the following code on the server:

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

    //Check if there is a parameter for the outfit id
     try {
        if (!req.getParameter("id").isEmpty() && Functions.isInteger(req.getParameter("id"))) {

            //Check if the requested id exists in the Cloud SQL database
            Connection conn = ConnectionManager.connectToCloudSQL();
            GetQueryBuilder query = DataManager.executeGet(conn, req, "outfit");

            //Check result
            if (query.getResultSet() == null) {
                throw new Exception("The Outfit object with the requested ID is not yet present in the Cloud SQL database");
            }

            Map<String,List<BlobKey>> blobs = blobstoreService.getUploads(req);
            BlobKey blobKey = blobs.get("image").get(0);

            if (blobKey == null) {
                throw new Exception("No blobkey specified");
            } 
            else {

               //First create a checksum from the file
               String checkSum = this.buildCheckSum(blobKey);

               PersistenceManager pm = PMF.get().getPersistenceManager();

               //Create new outfit object
               int outfitId = Integer.parseInt(req.getParameter("id"));
               OutfitExtension outfit = new OutfitExtension();
               outfit.setId(outfitId);
               outfit.setImage(blobKey);
               outfit.setCheckSum(checkSum);

               pm.makePersistent(outfit);

            }
        }
        else {
            throw new Exception("An outfit ID needs to be added to the HTTP request and should be from type Integer only.");
        }
    } catch (Exception e) {
        res.sendError(HttpServletResponse.SC_BAD_REQUEST, "Bad request: "+e.getMessage());
    }

}

This code is run when some URL is called (I have connected this in the web.xml). As you can see in the code, it is about blobstoreService.getUploads(req). How can I post Blob directly in which it is recognized as a upload?

1
  • Thanks for your comment! However, I have linked to that information myself. What extra info does it give me about this question? Commented Apr 15, 2015 at 7:53

2 Answers 2

1

This is a tricky one, I would advise you to perhaps have a look at this

However, I am inserting a code snippet that might answer your question in terms of you wanting to upload via code.


public static BlobKey toBlobstore(Blob imageData) throws FileNotFoundException, FinalizationException, LockException, IOException {
    if (null == imageData)
        return null;

    // Get a file service
    FileService fileService = FileServiceFactory.getFileService();

    // Create a new Blob file with mime-type "image/png"
    AppEngineFile file = fileService.createNewBlobFile("image/jpeg");// png

    // Open a channel to write to it
    boolean lock = true;
    FileWriteChannel writeChannel = fileService.openWriteChannel(file, lock);

    // This time we write to the channel directly
    writeChannel.write(ByteBuffer.wrap
        (imageData.getBytes()));

    // Now finalize
    writeChannel.closeFinally();
    return fileService.getBlobKey(file);
}


UPDATE: (For POST method):

// file Upload.java

import java.io.IOException;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.blobstore.BlobstoreService;
import com.google.appengine.api.blobstore.BlobstoreServiceFactory;

public class Upload extends HttpServlet {
    private BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();

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

        Map<String, List<BlobKey>> blobs = blobstoreService.getUploads(req);
        List<BlobKey> blobKeys = blobs.get("myFile");

        if (blobKeys == null || blobKeys.isEmpty()) {
            res.sendRedirect("/");
        } else {
            res.sendRedirect("/serve?blob-key=" + blobKeys.get(0).getKeyString());
        }
    }
}


That is what you can use to parse the image and upload it.

I hope this assists you :)

All the best!

Let me know of the outcome.

Good luck

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for your answer @TejjD, appreciate it! However, where can I specify the URL to which the write needs to be done? Also, the FileService is deprecated, so I am not keen on using that.
No problem at all. Glad I could shed some light. Where do you wish for it to be written to?
I would like to write it to the Blobstore using a POST url connection, see my updated question.
Alright I see what you mean. I have updated my answer, I am working on incorporating what the api, on the link you have already provided, says. I will get back to you on a solution as soon as possible :), I just had a look at your "Update 2" I will use that in finding a solution for you. Thanks
0

Any reason for not using Google Cloud storage instead of blobstore? See https://cloud.google.com/storage/docs/json_api/v1/libraries for information about the GCS standard library or https://github.com/GoogleCloudPlatform/appengine-gcs-client for a more convenient access from App Engine.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.