Tuesday, March 20, 2012

HttpClient vs HttpUrlConnection (Part 2/2)

HttpUrlConnection requires a different approach to maintaining a connection.  The official documentation reference CookieManager, but that is only for Api level 9 and I want to support Android 2.1 devices.  Also the compatibility package does not contain that network update.  So what to do?

Well I've found Ians Cookie Manager to help: http://www.hccp.org/java-net-cookie-how-to.html
Renamed this per the instructions at StackOverflow: http://stackoverflow.com/questions/6354294/urlconnection-with-cookies

In my BaseAppData singleton class is the info as shown below.
Usage is to call BaseAppData.getHttpUrlConnection(url) to get the connection object and it sets up the cookies which maintains your session.
When you are done accessing data, you need to call BaseAppData.closeHttpUrlConnection() to save the current cookie state.

I apologize for any errors in the code, I know that not all of the timeout/exception handling is there and I'm not sure how to do that yet for the HttpUrlConnection.

<code>

public class BaseAppData extends Application {
private static BaseAppData singleton;
private static HttpClient client;

private static IansCookieManager cm = new IansCookieManager();

public static BaseAppData getInstance() {
return singleton;
}




public static HttpURLConnection getHttpUrlConnection(String url) throws MalformedURLException,        
        IOException {
HttpURLConnection  conn = (HttpURLConnection) new URL(url).openConnection();
cm.setCookies(conn);
return (HttpURLConnection) conn;
}

public static void closeHttpUrlConnection(HttpURLConnection conn) throws IOException {
if (conn != null ) {
if (cm != null)
cm.storeCookies(conn);
conn.disconnect();
}
}
</code>

//Now to connect to the server to post and read data, NOTE: CHARSET is just

public static final String CHARSET = "UTF-8";
/**
* Used to login to the website - using HttpUrlConnection version
*
* @param client
* @param uname - set to null to check if user is already logged in
* @param pword - set to null to check if user is already logged in
* @return result obj.string will contain an int if user is logged in, otherwise is "", blank
*/
public static boolean login_helper_HttpUrlConnection(String uname, String pword, String host) {
Object result = null;
             
try {
String postURL = host+"page.php";
HttpURLConnection conn = BaseAppData.getHttpUrlConnection(postURL);

conn.setDoOutput(true); // Triggers POST.
conn.setRequestProperty("Accept-Charset", CHARSET);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset="+ CHARSET);

String query = "";
if (uname != null && pword != null) {
query = String.format("userid=%s&passwd=%s",
URLEncoder.encode(uname+"", CHARSET),
URLEncoder.encode(pword+"", CHARSET) );
}

OutputStream output = null;
try {
     output = conn.getOutputStream();
     output.write(query.getBytes(CHARSET));
} finally {
     if (output != null) try { output.close(); } catch (IOException logOrIgnore) {
   
    String error = "Could not send output to WebServer Error: "+logOrIgnore.getMessage()+", Cause: "+logOrIgnore.getCause();
    Log.e("login_helper_HttpUrlConnection", error );
     }
}
InputStream response_stream = conn.getInputStream();
   
BufferedReader reader = null;
String consume_str ="";
try {
reader = new BufferedReader(new InputStreamReader(response_stream, CHARSET));
   for (String line; (line = reader.readLine()) != null;) {
       consume_str+=line;
   }
 
} finally {
   if (reader != null) try {
    reader.close();
    BaseAppData.closeHttpUrlConnection(conn);
   } catch (IOException logOrIgnore) {
    result.success = false;
    result.error = "Could not read results from the WebServer Error: "+logOrIgnore.getMessage()+", Cause: "+logOrIgnore.getCause();
    Log.e("login_helper_HttpUrlConnection", result.error );

   }
}

             //I use JSON objects for results, but parse however you need
             result = new JSONObject(consume_str); //get main json
           
             JSONObject main = (JSONObject)result;
             result = main.getJSONObject("data"); //get actual data object
             }

    } catch (IOException e) {
    result = null;
    Log.e("login_helper_HttpUrlConnection", "IOException Error: "+e.getMessage()+", Cause: "+e.getCause() );
    } catch (JSONException e) {
    result = null;
    if (uname != null)
    Log.e("login_helper_HttpUrlConnection", "JSONException Error: "+e.getMessage()+", Cause: "+e.getCause() );
    else
    Log.d("login_helper_HttpUrlConnection", "Could not login using current Webserver Session, please supply username and password." );
    }
    return result;
}