How to call a RESTful web service from Android?

144,110

Solution 1

This is an sample restclient class

public class RestClient
{
    public enum RequestMethod
    {
        GET,
        POST
    }
    public int responseCode=0;
    public String message;
    public String response;
    public void Execute(RequestMethod method,String url,ArrayList<NameValuePair> headers,ArrayList<NameValuePair> params) throws Exception
    {
        switch (method)
        {
            case GET:
            {
                // add parameters
                String combinedParams = "";
                if (params!=null)
                {
                    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
                if (headers!=null)
                {
                    headers=addCommonHeaderField(headers);
                    for (NameValuePair h : headers)
                        request.addHeader(h.getName(), h.getValue());
                }
                executeRequest(request, url);
                break;
            }
            case POST:
            {
                HttpPost request = new HttpPost(url);
                // add headers
                if (headers!=null)
                {
                    headers=addCommonHeaderField(headers);
                    for (NameValuePair h : headers)
                        request.addHeader(h.getName(), h.getValue());
                }
                if (params!=null)
                    request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
                executeRequest(request, url);
                break;
            }
        }
    }
    private ArrayList<NameValuePair> addCommonHeaderField(ArrayList<NameValuePair> _header)
    {
        _header.add(new BasicNameValuePair("Content-Type","application/x-www-form-urlencoded"));
        return _header;
    }
    private void executeRequest(HttpUriRequest request, String url)
    {
        HttpClient client = new DefaultHttpClient();
        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);
                instream.close();
            }
        }
        catch (Exception e)
        { }
    }

    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");
            }
            is.close();
        }
        catch (IOException e)
        { }
        return sb.toString();
    }
}

Solution 2

Recently discovered that a third party library - Square Retrofit can do the job very well.


Defining REST endpoint

public interface GitHubService {
   @GET("/users/{user}/repos")
   List<Repo> listRepos(@Path("user") String user,Callback<List<User>> cb);
}

Getting the concrete service

RestAdapter restAdapter = new RestAdapter.Builder()
    .setEndpoint("https://api.github.com")
    .build();
GitHubService service = restAdapter.create(GitHubService.class);

Calling the REST endpoint

List<Repo> repos = service.listRepos("octocat",new Callback<List<User>>() { 
    @Override
    public void failure(final RetrofitError error) {
        android.util.Log.i("example", "Error, body: " + error.getBody().toString());
    }
    @Override
    public void success(List<User> users, Response response) {
        // Do something with the List of Users object returned
        // you may populate your adapter here
    }
});

The library handles the json serialization and deserailization for you. You may customize the serialization and deserialization too.

Gson gson = new GsonBuilder()
    .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
    .registerTypeAdapter(Date.class, new DateTypeAdapter())
    .create();

RestAdapter restAdapter = new RestAdapter.Builder()
    .setEndpoint("https://api.github.com")
    .setConverter(new GsonConverter(gson))
    .build();

Solution 3

Stop with whatever you were doing ! :)

Implement the RESTful client as a SERVICE and delegate the intensive network stuff to activity independent component: a SERVICE.

Watch this insightful video http://www.youtube.com/watch?v=xHXn3Kg2IQE where Virgil Dobjanschi is explaining his approach(es) to this challenge...

Solution 4

Using Spring for Android with RestTemplate https://spring.io/guides/gs/consuming-rest-android/

// The connection URL 
String url = "https://ajax.googleapis.com/ajax/" + 
    "services/search/web?v=1.0&q={query}";

// Create a new RestTemplate instance
RestTemplate restTemplate = new RestTemplate();

// Add the String message converter
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());

// Make the HTTP GET request, marshaling the response to a String
String result = restTemplate.getForObject(url, String.class, "Android");

Solution 5

I used OkHttpClient to call restful web service. It's very simple.

OkHttpClient httpClient = new OkHttpClient();
Request request = new Request.Builder()
                .url(url)
                .build();

Response response = httpClient.newCall(request).execute();
String body = response.body().string()
Share:
144,110
sudo
Author by

sudo

Updated on July 09, 2022

Comments

  • sudo
    sudo almost 2 years

    I have written a REST web service in Netbean IDE using Jersey Framework and Java.

    For every request the user needs to provide a username and a password, I know that this authentication is not a best practice (using a curl command like: curl -u username:password -X PUT http://localhsot:8080/user).

    Now I want to call a REST web service from an Android Class.

    How should I do it?

    I have an Android Class which uses DefaultHttpClient and CredentialUsernameAndPassword, but when I run it in Eclipse, sometimes I get a runtime exception or SDK exception.

  • Gatunox
    Gatunox about 9 years
    is there any real example about this? i don't quite understand in detail.
  • Tianhai
    Tianhai about 9 years
    Retrofit generates the Restful web services clients for you. You just need to define interfaces with some annotations. For details, see square.github.io/retrofit
  • Gatunox
    Gatunox about 9 years
    I already look at it. But o still dont get it. Trats why im looking for an real example. No just a few pieces of code
  • Tianhai
    Tianhai about 9 years
  • Chris Cirefice
    Chris Cirefice almost 9 years
    I have been using Retrofit for a few months and have never had better success with a Java library in my life. I recommend using Google's Gson library with it, as it makes JSON (de)serialization really really easy.
  • Czechnology
    Czechnology over 7 years
    That's not a built-in component of Android.
  • J. Schei
    J. Schei about 7 years
    Adding a class's source code without comments or summarizing what is happening at which point is confusing to someone new to RESTful services such as myself.
  • jk7
    jk7 about 7 years
    Those who down-voted should explain what is wrong with this answer.