Java – Best Approach: HTTP POST (multi-part) from Android to GAE

Best Approach: HTTP POST (multi-part) from Android to GAE… here is a solution to the problem.

Best Approach: HTTP POST (multi-part) from Android to GAE

I want to capture an image from a camera on Android and send it to Google App Engine, which stores the image in blob storage. As simple as it sounds, I can get multipart POST to GAE to happen, but storing to blob storage requires servlets to return HTTP redirects (302). So I need a connection that can follow the redirect after performing HTTP POST. Here’s the code I hope will work :

public static String sendPhoto(String myUrl, byte[] imageData) {
    HttpURLConnection connection = null;
    DataOutputStream outputStream = null;
    String pathToOurFile = "/data/file_to_send.jpg";
    String urlServer = myUrl;
    String lineEnd = "\r\n";
    String twoHyphens = "--";
    String boundary = "*****";
     Please follow redirects
    HttpURLConnection.setFollowRedirects(true);
    BufferedReader rd = null;
    StringBuilder sb = null;
    String line = null;
    try {
        URL url = new URL(urlServer);
        connection = (HttpURLConnection) url.openConnection();
         Allow Inputs & Outputs
        connection.setDoInput(true);
        connection.setDoOutput(true);
        connection.setUseCaches(false);
         I really want you to follow redirects
        connection.setInstanceFollowRedirects(true);
        connection.setConnectTimeout(10000);  10 sec
        connection.setReadTimeout(10000);  10 sec
         Enable POST method
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Connection", "Keep-Alive");
        connection.setRequestProperty("Content-Type",
            "multipart/form-data; boundary=" + boundary);
        connection.connect();
        outputStream = new DataOutputStream(connection.getOutputStream());
        outputStream.writeBytes(twoHyphens + boundary + lineEnd);
        outputStream
                .writeBytes("Content-Disposition: form-data; name="
                    + "\"file1\"; filename=\""
                    + pathToOurFile + "\"" + lineEnd);
        outputStream.writeBytes(lineEnd);
        outputStream.write(imageData);
        outputStream.writeBytes(lineEnd);
        outputStream.writeBytes(twoHyphens + boundary + twoHyphens
            + lineEnd);
        outputStream.flush();
        outputStream.close();
        rd = new BufferedReader(new InputStreamReader(
                connection.getInputStream()));
        sb = new StringBuilder();
        while ((line = rd.readLine()) != null) {
            sb.append(line + '\n');
        }
        Log.i("Response: ", sb.toString());
         Responses from the server (code and message)
        int serverResponseCode = connection.getResponseCode();
        String serverResponseMessage = connection.getResponseMessage();
        Log.i("Response: serverResponseCode:",
            String.valueOf(serverResponseCode));
        Log.i("Response: serverResponseMessage:", serverResponseMessage);
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

As best I can, this code doesn’t follow the redirect. Enter steam always empty and response always 302. Although the pictures upload well. I would appreciate it if someone could tell me how to make it follow a redirect so I can read the response.

Or, if there’s a better way, I’d love to hear it. I know there are libraries like Apache HTTP Client out there, but it requires so many dependencies that it seems too bloated for a simple task.

Thanks

Solution

I was trying to do the same thing a few months ago!

Basically, don’t use HttpURLConnection. Instead, use HttpClient and HttpGet from the org.apache.http package, which are part of the Android SDK.

Unfortunately, I don’t have the source code to provide examples, but hopefully this points you in the right direction.

Related Problems and Solutions