Adding REST Webservice Functionality

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:

&lt;uses-permission android:name="android.permission.INTERNET"&gt;&lt;/uses-permission&gt;

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&gt; 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() &gt; 1) {
				res += "&amp;" + 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&gt; 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&gt; 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);
	}
}
About

Engineer at Facebook

Tagged with: , , , , , , ,
Posted in Android, Programming

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">