Question

I'm attempting to upload an image to the blobstore from Android but when my server servlet is called upon completion, the Blobstore fails to hand off any BlobKeys. And when I check the actual blobstore, no image has been uploaded. There is no error code, no warnings, no errors, nothing. Now I know the server stuff works because the upload works in iOS. And the Android code works just fine on the local development server but it's not working in production. I'm hoping that maybe someone can spot an error in my code.

Thanks in advance.

HttpURLConnection connection = null;

    try {

        Log.d(LOG_TAG, "Starting multipart POST request to: " +fullUrlValue);

        URL fullUrl = new URL(fullUrlValue);

        //make server call
        connection = getClient().getConnection(fullUrl, RequestMethod.POST);
        connection.setConnectTimeout(60000); //60 seconds to complete an upload 
        connection.setUseCaches(false);
        connection.setDoInput(true);
        connection.setDoOutput(true);

        //see if we are streaming the upload
        if(requestOptions == null || requestOptions.isChunckedStreamingMode())
        {
            connection.setChunkedStreamingMode(2048);
        }

        String boundry = "z6fQbdm2TTgLwPQj9u1HjAM25z9AJuGSx7WG9dnD";

        connection.setRequestProperty("Connection", "Keep-Alive");
        connection.setRequestProperty("Cache-Control", "no-cache");
        connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundry);

        //attach post objects
        DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());

        //add form fields
        if(additionalParameters != null && additionalParameters.keySet().size() > 0)
        {
            Iterator<String> it = additionalParameters.keySet().iterator();
            while(it.hasNext())
            {
                String fieldName = it.next();
                if(fieldName != null)
                {
                    String value = additionalParameters.get(fieldName);
                    if(value != null)
                    {
                        //add form field to upload form
                        outputStream.writeBytes("--" + boundry + "\r\n" + "Content-Disposition: form-data; name=\"" + fieldName + "\"\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\n"+value+"\r\n");
                    }
                }
            }
        }

        //attach file
        if(postObjectBytes != null)
        {   
            //build the request body
            outputStream.writeBytes("--" + boundry + "\r\n" + "Content-Disposition: form-data; name=\"" + formElementName + "\";filename=\"" + fileName + "\"\r\n\r\n");


            //object upload content size
            long totalUploadSize = postObjectBytes.length;

            //we have to manually process the stream in order to correctly update the progress listener
            byte[] buffer = new byte[2048];
            long totalBytes = 0;
            int bytesRead = 0;

            InputStream inputStream = new ByteArrayInputStream(postObjectBytes);

            while ((bytesRead = inputStream.read(buffer)) > -1) {
                totalBytes += bytesRead;
                outputStream.write(buffer, 0, bytesRead);

                if(progressListener != null){
                    progressListener.transferred(totalBytes, totalUploadSize);
                }
            }

            outputStream.writeBytes("\r\n--" + boundry + "--\r\n");

        }

        outputStream.flush();
        outputStream.close();
Was it helpful?

Solution

Well, I found the answer thanks to AppEngine BlobStore upload failing with a request that works in the Development Environment .

Apparently I was missing a space between the semi-colon and the start of "filename". That's just insane.

formElementName + "\";filename
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top