Wednesday, May 4, 2011

Android Java - how to stream UTF-8 bytes using HttpURLConnection

Here's the code I have written for communication between the Android app and the backend server. You may want to encrypt your byte data.

Note that in the following code, I do not depend on the Content-Length to get the data. I use a 4096 byte buffer to read data until there are no data. I used to depend on the Content-Length to retrieve data from the data. However, when I was testing using Nexus S on Android SDK 2.3, the content length was null. After some investigation, I found that the server was sending gzip data and it wipes out the content length variable.


Here's the http connection code:

public static String getHttpWithResponse(String urlStr, byte[] data) {
 
  String responseFromServer = null;
  HttpURLConnection con = null;
 
  try {

   URL url = new URL(urlStr);
   con = (HttpURLConnection) url.openConnection();
   con.setReadTimeout(50000);
   con.setConnectTimeout(20000);

   con.setRequestProperty("Connection", "Keep-Alive");

   con.setInstanceFollowRedirects(true);
   con.setRequestProperty("Content-Type",
     "application/x-www-form-urlencoded");

   con.setRequestMethod("GET");

   con.setDoInput(true);
  
   if (data != null) {

    String lineEnd = "\r\n";
    String twoHyphens = "--";
    String boundary = "*****************************************";

    con.setRequestMethod("POST");
    con.setDoOutput(true);
    con.setRequestProperty("Content-Type",
      "multipart/form-data;boundary=" + boundary);
    con.setRequestProperty("Content-Disposition",
      "multipart/form-data");
    OutputStream o = con.getOutputStream();
    o.write(data, 0, data.length);
    o.close();
   } else {
    con.setInstanceFollowRedirects(true);
    con.setRequestProperty("Content-Type",
      "application/x-www-form-urlencoded");

    con.setRequestMethod("GET");
   }
  
   if (con.getResponseCode() != HttpURLConnection.HTTP_OK) {
    throw new Exception("Response is not empty");
   }
  
   InputStream i = con.getInputStream();
  
   ByteArrayOutputStream bs = new ByteArrayOutputStream();
   byte[] bytesToRead = new byte[4096];

   int actuallyRead = 0;

   while (true) {
    int currentlyRead = i.read(bytesToRead, 0,
      bytesToRead.length);

    if (currentlyRead <= 0)
     break;

    bs.write(bytesToRead, 0, currentlyRead);
    actuallyRead += currentlyRead;

   }

   bytesToRead = null;
   i.close();

   if (actuallyRead < 0) {
    throw new Exception("Nothing Read");
   }

   bytesToRead = bs.toByteArray();

   responseFromServer = new String(bytesToRead, "UTF-8");
  
  } catch (Exception e) {
   responseFromServer = null;
  } finally {
   if (con != null) {
    con.disconnect();
   }
  }

  return responseFromServer;
 }

No comments:

Post a Comment