For one of my current projects, bpstats.com, I needed to learn how to interface with a REST webservice from an Android application.
Here is a tutorial for creating a generic REST webservice client for the Android SDK.
First, create a new Android project and related Android Test Project via Eclipse File->New Project->Android Project
This will automatically create a project for the RestClient and a project for unitTesting
//PRO TIP: Let eclipse create the project and the test project for you: it will save you major headaches later trying to update the xml config files
//PRO TIP: Make sure the manifest file in your project, not the test project, has the following line in between the <manifest> </manifest> tags:
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
This will save you a major headache later (if you don’t have this line, you get a socket exception)
Now that the manifests are up to date, its time to create a RestClient and a RestClientTest:
Here is my code for a generic RestClient with only the GET method available and all exceptions thrown for debugging purposes (this will be important for unitTesting)
package com.eosgood.rest; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; import java.net.URLEncoder; import java.util.HashMap; import java.util.Iterator; import java.util.Map.Entry; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.util.Log; public class RestClient { public static final String TAG = "RestClient"; public static final int POST = 0; public static final int GET = 1; public static final int JSON = 2; public static final int XML = 3; private String url; private String responsePhrase; private String response; private JSONArray recvObj; private int respCode; private HashMap params; private HashMap headers; public RestClient(String restUrl) { this.url = restUrl; this.params = new HashMap(); this.headers = new HashMap(); } public String getResponse() { return this.response; } public String getErrorMsg() { return this.responsePhrase; } public int getResponseCode(){ return this.respCode; } public void addParam(String key, String value){ this.params.put(key, value); } public void addHeader(String key, String value){ this.headers.put(key, value); } public String buildParams() throws UnsupportedEncodingException { Iterator> it = params.entrySet().iterator(); String res = "?"; while (it.hasNext()) { Entry pair = it.next(); String add = pair.getKey() + "=" + URLEncoder.encode(pair.getValue(), "UTF-8"); if (params.size() > 1) { res += "&" + add; } else { res += add; } } return res; } public String convertStreamToString(InputStream is) throws IOException { if (is != null) { Writer writer = new StringWriter(); char[] buffer = new char[1024]; try { Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8")); int n; while ((n = reader.read(buffer)) != -1) { writer.write(buffer, 0, n); } } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { is.close(); } return writer.toString(); } else { return ""; } } public void sendHttpPost() throws ClientProtocolException, IOException{ HttpPost httpPostRequest = new HttpPost(url + buildParams()); // add headers Iterator> it = headers.entrySet().iterator(); while (it.hasNext()) { Entry header = it.next(); httpPostRequest.addHeader(header.getKey(), header.getValue()); } HttpClient client = new DefaultHttpClient(); HttpResponse resp; resp = client.execute(httpPostRequest); this.respCode = resp.getStatusLine().getStatusCode(); Log.i(TAG, "response code: " + getResponseCode()); this.responsePhrase = resp.getStatusLine().getReasonPhrase(); Log.i(TAG, "error msg: " + getErrorMsg()); HttpEntity entity = resp.getEntity(); if (entity != null){ InputStream is = entity.getContent(); //Header contentEncoding = resp.getFirstHeader("Content-encoding"); //Log.i(TAG, "endoding" + contentEncoding.getValue()); response = convertStreamToString(is); //response = response.substring(1,response.length()-1); //response = "{" + response + "}"; Log.i(TAG, "response: " + response); is.close(); } } public void callWebService(int method) throws IllegalStateException, ClientProtocolException, IOException { switch (method) { case GET: // build correct url HttpGet request = new HttpGet(url + buildParams()); // add headers Iterator> it = headers.entrySet().iterator(); while (it.hasNext()) { Entry header = it.next(); request.addHeader(header.getKey(), header.getValue()); } // exec request HttpClient client = new DefaultHttpClient(); HttpResponse resp; resp = client.execute(request); this.respCode = resp.getStatusLine().getStatusCode(); this.responsePhrase = resp.getStatusLine().getReasonPhrase(); HttpEntity entity = resp.getEntity(); if (entity != null) { InputStream is = entity.getContent(); response = this.convertStreamToString(is); response = response.substring(1,response.length()-1); response = "{" + response + "}"; Log.i(TAG, "response: " + response); is.close(); } break; case POST: sendHttpPost(); } } public void createObjectJson() throws JSONException{ this.recvObj = new JSONArray(this.response); Log.i(TAG, "json object" + recvObj.toString() + "/json object"); } }
Here is a small junit test that makes a JSONArray from HttpPost:
package com.eosgood.rest.test; import java.io.IOException; import org.apache.http.client.ClientProtocolException; import org.json.JSONException; import com.eosgood.rest.RestClient; import junit.framework.TestCase; public class RestClientTest extends TestCase { public void testClientGet(){ RestClient ri = new RestClient("urlhere"); //ri.addParam("httpcontext", "application/json"); ri.addHeader("Accept", "application/json"); ri.addHeader("Content-type", "application/json"); try { ri.callWebService(RestClient.POST); } catch (IllegalStateException e) { assertTrue(e.getLocalizedMessage(), false); e.printStackTrace(); } catch (ClientProtocolException e) { assertTrue(e.getLocalizedMessage(), false); e.printStackTrace(); } catch (IOException e) { assertTrue(e.getLocalizedMessage(), false); e.printStackTrace(); } try { ri.createObjectJson(); } catch (JSONException e) { assertTrue(e.getLocalizedMessage(), false); e.printStackTrace(); } assertTrue(ri.getResponse(), false); } }