0

I have an Endpoints API method that gives me an upload URL to Google Cloud Storage like this:

@ApiMethod(name = "getUploadUrl", path = "get_upload_url", httpMethod = ApiMethod.HttpMethod.POST)
    public CollectionResponse<String> getUploadUrl(@Named("objectName")String objectName){

        BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
        String callbackUrl = "/handleupload";
        String uploadUrl = blobstoreService.createUploadUrl(callbackUrl,
                UploadOptions.Builder.withGoogleStorageBucketName("my-bucket"));

        ArrayList<String> results = new ArrayList<>(1);
        results.add(uploadUrl);
        return CollectionResponse.<String>builder().setItems(results).build();
    }

This successfully returns a URL for me to upload my image file to.

In Android, I try to upload the file like this:

private Boolean uploadImage(File file, String uploadUrl){
        try {
            long bytes = file.length();

            URL url = new URL(uploadUrl);
            HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
            urlConnection.setRequestMethod("POST"); 
            urlConnection.setDoInput(true);
            urlConnection.setDoOutput(true);
            urlConnection.setRequestProperty("Connection", "Keep-Alive");
            urlConnection.setRequestProperty("Content-Type", "image/jpg");

            DataOutputStream outputStream = new DataOutputStream(urlConnection.getOutputStream());

            int bytesAvailable = 0;
            FileInputStream fileInputStream = null;
            try {
                fileInputStream = new FileInputStream(file);
                bytesAvailable = fileInputStream.available();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                return false;
            }

            int maxBufferSize = 1024;
            int bufferSize = Math.min(bytesAvailable, maxBufferSize);
            byte[ ] buffer = new byte[bufferSize];

            int bytesRead = fileInputStream.read(buffer, 0, bufferSize);

            while (bytesRead > 0)
            {
                outputStream.write(buffer, 0, bufferSize);
                bytesAvailable = fileInputStream.available();
                bufferSize = Math.min(bytesAvailable,maxBufferSize);
                bytesRead = fileInputStream.read(buffer, 0,bufferSize);
            }
            int responseCode = urlConnection.getResponseCode();

            fileInputStream.close();
            outputStream.flush();
            outputStream.close();

        } catch (IOException e) {
            e.printStackTrace();
        }

        return false;
    }

But I get back a response of 400 Bad Request. I think I am doing something wrong.

I would like to use the HttpURLConnection class because Android recommends it over HttpClient (which is what most SO posts have examples of): http://android-developers.blogspot.com/2011/09/androids-http-clients.html

And I am using the blobstore api to upload an image instead of a Google Cloud Storage Signed URL because I can get a callback server-side to handle the upload.

Micro
  • 10,303
  • 14
  • 82
  • 120

1 Answers1

0

I never tried it myself, so I am not 100% sure. However the public documentation does suggest the request must "include a file upload field, and the form's enctype must be set to multipart/form-data." There are various examples that show how to send such a request using HttppUrlConnection. (This is one example, though make sure you use "file" instead of "filename").

Community
  • 1
  • 1
ozarov
  • 1,051
  • 6
  • 7