1

I found an API for which I want to play as I am free. I want to ask if I want to develop Android app using the API and the API is HTTP protocol based (RESTful), how can I use the HTTPClient object to do so?

I have a general request info.

HEAD /authenticate/ HTTP/1.1
Host: my.api.com
Date: Thu, 17 Jul 2008 14:52:54 GMT
X-SE-Client: some-value
X-SE-Accept: xml
X-SE-Auth: 90a6d325e982f764f86a7e248edf6a660d4ee833

The response of the above would be if success.

HTTP/1.1 200 OK
Date: Thu, 17 Jul 2008 14:52:55 GMT
Server: MyApi
Content-Length: 795
Connection: close
Content-Type: text/xml

I know how to use HTTPClient to send HTTP requests but does it add extra headers and other unnecessary stuff to the request? How can I see the request made by HTTPClient object? I want to simply request passing text like in telnet.

Umair A.
  • 6,690
  • 20
  • 83
  • 130

2 Answers2

4

You should be able to use HttpClient in Android to do what you need. I just finished the first part of an integration of Android with an ASP.NET MVC 3 site and I must say - it was quite painless. I use Json as my data exchange format.

You can view exactly what the header looks like by setting a debug point after building your request. Here is some sample code (please remember it is just sample code - not a full implementation).

This class is called by a separate thread than the UI thread:

public class RemoteDBAdapter {


    public String register(String email, String password) throws Exception
    {
        RestClient c = new RestClient("http://myurl/Account/Register");
        c.AddHeader("Accept", "application/json");
        c.AddHeader("Content-type", "application/json");
        c.AddParam("Email", email);
        c.AddParam("Password", password);

        c.Execute(RequestMethod.POST);

        JSONObject key = new JSONObject(c.getResponse());

        return key.getString("status");


    }

}

Use this class to build your request and execute it:

public class RestClient {

    public enum RequestMethod {
        GET,
        POST
    }

    private ArrayList <NameValuePair> params;
    private ArrayList <NameValuePair> headers;

    private String url;

    private int responseCode;
    private String message;

    private String response;

    public String getResponse() {
        return response;
    }

    public String getErrorMessage() {
        return message;
    }

    public int getResponseCode() {
        return responseCode;
    }

    public RestClient(String url)
    {
        this.url = url;
        params = new ArrayList<NameValuePair>();
        headers = new ArrayList<NameValuePair>();
    }

    public void AddParam(String name, String value)
    {
        params.add(new BasicNameValuePair(name, value));
    }

    public void AddHeader(String name, String value)
    {
        headers.add(new BasicNameValuePair(name, value));
    }

    public void Execute(RequestMethod method) throws Exception
    {
        switch(method) {
            case GET:
            {
                //add parameters
                String combinedParams = "";
                if(!params.isEmpty()){
                    combinedParams += "?";
                    for(NameValuePair p : params)
                    {
                        String paramString = p.getName() + "=" + URLEncoder.encode(p.getValue(),"UTF-8");
                        if(combinedParams.length() > 1)
                        {
                            combinedParams  +=  "&" + paramString;
                        }
                        else
                        {
                            combinedParams += paramString;
                        }
                    }
                }

                HttpGet request = new HttpGet(url + combinedParams);

                //add headers
                for(NameValuePair h : headers)
                {
                    request.addHeader(h.getName(), h.getValue());
                }

                executeRequest(request, url);
                break;
            }
            case POST:
            {
                HttpPost request = new HttpPost(url);

                //add headers
                for(NameValuePair h : headers)
                {
                    request.addHeader(h.getName(), h.getValue());
                }
                JSONObject jo = new JSONObject();


                if(!params.isEmpty()){
                    for (int i = 0; i < params.size();i++)
                    {
                        jo.put(params.get(i).getName(),params.get(i).getValue());


                    }
                    StringEntity se = new StringEntity(jo.toString());
                    se.setContentType("text/xml"); 
                    se.setContentEncoding( new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); 

                    request.setEntity(se);
                    //request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
                }

                executeRequest(request, url);
                break;
            }
        }
    }

    private void executeRequest(HttpUriRequest request, String url)
    {
        //HttpClient client = new DefaultHttpClient();
        HttpClient client = HttpClientFactory.getThreadSafeClient();

        HttpResponse httpResponse;

        try {
            httpResponse = client.execute(request);
            responseCode = httpResponse.getStatusLine().getStatusCode();
            message = httpResponse.getStatusLine().getReasonPhrase();

            HttpEntity entity = httpResponse.getEntity();

            if (entity != null) {

                InputStream instream = entity.getContent();
                response = convertStreamToString(instream);

                // Closing the input stream will trigger connection release
                instream.close();
            }

        } catch (ClientProtocolException e)  {
            client.getConnectionManager().shutdown();
            e.printStackTrace();
        } catch (IOException e) {
            client.getConnectionManager().shutdown();
            e.printStackTrace();
        }
    }

    private static String convertStreamToString(InputStream is) {

        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();

        String line = null;
        try {
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }
}

EDIT:

Oh ya and the HttpClientFactory:

// Should be thread safe
public class HttpClientFactory {

            private static DefaultHttpClient client;

            public synchronized static DefaultHttpClient getThreadSafeClient() {
                    if (client != null)
                            return client;
                    client = new DefaultHttpClient();
                    ClientConnectionManager mgr = client.getConnectionManager();
                    HttpParams params = client.getParams();
                    client = new DefaultHttpClient(new ThreadSafeClientConnManager(params,
                                    mgr.getSchemeRegistry()), params);
                return client;

            }
    }
Jack
  • 9,156
  • 4
  • 50
  • 75
  • I tired your code too. It was giving the same 400 error as the HTTPClient object way. I managed to figure out your and my both codes were correct and error was of URI being not made properly. Silly me. Many thanks for your efforts! – Umair A. Aug 09 '11 at 21:07
  • No problem. The code could be improved upon of course, but you get the point :). – Jack Aug 09 '11 at 21:18
0

REST is much more strict about the formats you use vs. older SOAP methods.

If you want to pass a single string or something like that, I suggest using JSON within REST. REST with XML is used for more complex structures like nested XML payloads and that sort of thing. JSON will also likely be much faster. There is built in support for JSON in Android, as well.

Codeman
  • 12,157
  • 10
  • 53
  • 91
  • When I said I am using SOAP? It's RESTful API and I am calling using HTTPClient object of the Java for Android. – Umair A. Aug 09 '11 at 18:38
  • I was only stating that REST is more complex. You can't pass simple strings, you always need a header and parameters. The implementation above is correct, but I don't believe this answer deserves a downvote. – Codeman Aug 09 '11 at 18:53
  • Read what I meant, not what I said. :) The answer still didn't deserve a downvote :) – Codeman Aug 10 '11 at 13:31