Logo Icon Logo
A Crowd-sourced Cookbook on Writing Great Android® Apps
GitHub logo Twitter logo OReilly Book Cover Art

Consuming a RESTful Web Service using URLConnection

Author: Ian Darwin
Published? true -- FormatLanguage: W

Problem:

You need to access a RESTful Web Service.

Solution:

You can either use the "standard" Java URL and URLConnection objects, or you can use the Android-provided Apache HTTPClient library to code at a slightly higher level or to use HTTP methods other than GET and POST.

Discussion:

REST was originally intended as an architectural description of the early Web, in which GET requests were used and in which the URL fully specified (Represented) the State of the request. Today RESTful web services are those which eschew the overhad of XML SOAP, WSDL and (usually) XML Schema, and simply send URLs that contain all the information needed to perform the request (or almost all, there is often a POST body sent for some types of requests). For example, to support an Android client that allows off-line editing of Recipes for this Android Cookbook, there is a (draft) Web Service which allows you to view the list of Recipes (you send an HTTP GET request ending in /recipe/list), to view the details of one Recipe (HTTP GET ending in /recipe/NNN where NNN is the primary key of the entry, gotten from the list request above), and later upload your revised version of the Recipe using HTTP POST to /recipe/NNN with the POST body containing the revised Recipe in the same XML document format as the "get Recipe" operation downloads it.

N.B. Both these examples only show fetching the results. You already know that you can't run a REST service from an Activity (use a Service), and that you can't update the UI from a Service (use a Handler).`

By the way, the RESTful Service used by these examples - to retreive recipes from the Android Cookbook site - is implemented in server-side Java using the JAX-RS API, provided by JBoss Seam using RestEasy.

Contents


Using URL and URLConnection

Android's developers wisely preserved a lot of the Java standard API, including some widely-used classes for networking, so as to make it easy to port existing code. The converse() method shown below uses a URL and URLConnection from java.net to do a GET, and is extracted from an example in the networking chapter of my Java Cookbook. Comments in this version show what you'd need to change to do a POST.

    public static String converse(String host, int port, String path) throws IOException {
	URL url = new URL("http", host, port, path);
        URLConnection conn = url.openConnection();
        // This does a GET; to do a POST, add conn.setDoInput(true);
        conn.setDoOutput(true);
        conn.setAllowUserInteraction(true);
        
        conn.connect();
	
        // To do a POST, you'd write to conn.getOutputStream());

        StringBuilder sb = new StringBuilder();
        BufferedReader in = new BufferedReader(
        	new InputStreamReader(conn.getInputStream()));
        String line;
        while ((line = in.readLine()) != null) {
            sb.append(line);
        }
        in.close();
        return sb.toString();
    }

The invocation of this method in, say, your onResume() or onCreate() method, can be as simple as the following, which gets the list of Recipes from this Android Cookbook:

String host = "androidcookbook.net";
String path = "/seam/resource/rest/recipe/list";
String ret = converse(host, 80, path);

Using HTTPClient

Android supports the Apache HTTPClient library which is widely used for communicating at a slightly higer level than the URLConnection. I've used it in my PageUnit web test framework. HttpClient also lets you use other HTTP methods that are common in RESTful services, such as PUT, DELETE, etc. (he URLConnection object used above, by contrast, only supports GET and POST(?)). Here's the same converse method coded for a GET using HTTPClient:

	public static String converse(String host, int port, String path, String postBody) throws IOException {
		HttpHost target = new HttpHost(host, port);
		HttpClient client = new DefaultHttpClient();
		HttpGet get = new HttpGet(path);
		HttpEntity results = null;
		try {
			HttpResponse response=client.execute(target, get);
			results = response.getEntity();
			return EntityUtils.toString(results);
		} catch (Exception e) {
			throw new RuntimeException("Web Service Failure");
		} finally {
			if (results!=null)
				try {
					results.consumeContent();
				} catch (IOException e) {
					// empty, Checked exception but don't care
				}
		}
	}

Usage will be exactly the same as for the URLConnection-based version.

The Results

In the present version of the web service, the return value comes back as an XML document, which you'd need to parse to display in a List. If there is enough interest, we might add a JSON version as well.

Note

Don't forget to add the android.permission.INTERNET Permission to your AndroidManifest.xml or you will not be able to access any web connections.

See Also:

Using a SOAP Web Service, Parsing an XML document using the DOM API, Displaying a List

No records found.