com.touchsi.sutee.android.rest.RestClient.java Source code

Java tutorial

Introduction

Here is the source code for com.touchsi.sutee.android.rest.RestClient.java

Source

/*
 * RestClient.java
 *
 * Provides an asynchronized Android REST client.
 *
 * Copyright (c) 2012 Sutee Sudprasert.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Software written by:
 * Sutee Sudprasert  <sutee.s@gmail.com>
 */

package com.touchsi.sutee.android.rest;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.AbstractHttpMessage;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;

import android.os.Handler;
import android.util.Log;

/**
 * RestClient.java Credit to Luke Lowrey for his code for RestClient which makes
 * call to web services in a pretty neat way. Here is the code for RestClient
 * class that uses org.apache.http library which is included in Android.
 * 
 * @see http://lukencode.com/2010/04/27/calling-web-services-in-android-using-httpclient/
 * 
 * @author Luke Lowrey
 * @author Sutee Sudprasert (refactoring and improvement)
 */

public class RestClient {

    ExecuteRequest mExecuteRequest;

    public class ExecuteRequest {

        private RequestMethod mMethod;
        private int mResponseCode;
        private String mMessage;
        private String mResponse;
        private Exception mError;

        public void finish(RequestMethod method, HttpResponse httpResponse, String response) {
            mMethod = method;
            mResponseCode = httpResponse.getStatusLine().getStatusCode();
            mMessage = httpResponse.getStatusLine().getReasonPhrase();
            mResponse = response;
        }

        public void error(Exception e) {
            mError = e;
        }

        public void execute(HttpUriRequest request, String url, RequestMethod method) {
            final HttpClient client = new DefaultHttpClient();

            try {
                final HttpResponse httpResponse = client.execute(request);
                Log.d("RestClient", httpResponse.getAllHeaders().toString());
                String response = null;
                if (httpResponse.getEntity() != null) {
                    try {
                        InputStream instream = httpResponse.getEntity().getContent();
                        response = convertStreamToString(instream);
                        instream.close();
                    } catch (IllegalStateException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                finish(method, httpResponse, response);
            } catch (final ClientProtocolException e) {
                client.getConnectionManager().shutdown();
                e.printStackTrace();
                error(e);
            } catch (final IOException e) {
                client.getConnectionManager().shutdown();
                e.printStackTrace();
                error(e);
            }
        }

        public RequestMethod getMethod() {
            return mMethod;
        }

        public int getResponseCode() {
            return mResponseCode;
        }

        public String getResponse() {
            return mResponse;
        }

        public String getMessage() {
            return mMessage;
        }

        public Exception getError() {
            return mError;
        }
    }

    public class AsyncExecuteRequest extends ExecuteRequest {

        private OnRequestFinishListener onRequestFinishListener;
        private Handler mHandler;

        public AsyncExecuteRequest(Handler handler, OnRequestFinishListener onRequestFinishListener) {
            mHandler = handler;
            this.onRequestFinishListener = onRequestFinishListener;
        }

        public void setHandler(Handler handler) {
            mHandler = handler;
        }

        public void setOnRequestFinishListener(OnRequestFinishListener onRequestFinishListener) {
            this.onRequestFinishListener = onRequestFinishListener;
        }

        private void notifyRequestFinish(RequestMethod method, int responseCode, String message, String response) {
            if (onRequestFinishListener != null) {
                onRequestFinishListener.onRequestFinish(method, responseCode, message, response);
            }
        }

        private void notifyRequestFinishWithError(Exception e) {
            if (onRequestFinishListener != null) {
                onRequestFinishListener.onRequestFinishWithError(e);
            }
        }

        @Override
        public void finish(final RequestMethod method, final HttpResponse httpResponse, final String response) {
            super.finish(method, httpResponse, response);
            if (mHandler != null) {
                mHandler.post(new Runnable() {
                    public void run() {
                        notifyRequestFinish(method, httpResponse.getStatusLine().getStatusCode(),
                                httpResponse.getStatusLine().getReasonPhrase(), response);
                    }
                });
            }
        }

        @Override
        public void error(final Exception e) {
            super.error(e);
            if (mHandler != null) {
                mHandler.post(new Runnable() {
                    public void run() {
                        notifyRequestFinishWithError(e);
                    }
                });
            }
        }
    }

    public static enum RequestMethod {
        GET, POST, PUT, DELETE
    }

    public abstract static class RestMethod {
        public abstract RequestMethod getMethodType();

        public abstract void executeRequest(RestClient client) throws UnsupportedEncodingException;
    }

    public static class GetMethod extends RestMethod {

        @Override
        public RequestMethod getMethodType() {
            return RequestMethod.GET;
        }

        @Override
        public void executeRequest(RestClient client) throws UnsupportedEncodingException {
            // add parameters
            String combinedParams = "";
            if (!client.params.isEmpty()) {
                combinedParams += "?";
                for (NameValuePair p : client.params) {
                    String paramString = p.getName() + "=" + URLEncoder.encode(p.getValue(), "UTF-8");
                    if (combinedParams.length() > 1) {
                        combinedParams += "&" + paramString;
                    } else {
                        combinedParams += paramString;
                    }
                }
            }
            HttpGet request = new HttpGet(client.url + combinedParams);
            client.addHeaders(request);
            client.executeRequest(request, client.url, getMethodType());
        }
    }

    public static class PostMethod extends RestMethod {

        @Override
        public RequestMethod getMethodType() {
            return RequestMethod.POST;
        }

        @Override
        public void executeRequest(RestClient client) throws UnsupportedEncodingException {
            HttpPost request = new HttpPost(client.url);
            client.addHeaders(request);

            if (!client.params.isEmpty()) {
                request.setEntity(new UrlEncodedFormEntity(client.params, HTTP.UTF_8));
            }

            client.executeRequest(request, client.url, getMethodType());
        }

    }

    public static class DeleteMethod extends RestMethod {

        @Override
        public RequestMethod getMethodType() {
            return RequestMethod.DELETE;
        }

        @Override
        public void executeRequest(RestClient client) throws UnsupportedEncodingException {
            HttpDelete request = new HttpDelete(client.url);
            client.addHeaders(request);

            client.executeRequest(request, client.url, getMethodType());
        }

    }

    public static class PutMethod extends RestMethod {

        @Override
        public RequestMethod getMethodType() {
            return RequestMethod.PUT;
        }

        @Override
        public void executeRequest(RestClient client) throws UnsupportedEncodingException {
            HttpPut request = new HttpPut(client.url);
            client.addHeaders(request);

            if (!client.params.isEmpty()) {
                request.setEntity(new UrlEncodedFormEntity(client.params, HTTP.UTF_8));
            }

            client.executeRequest(request, client.url, getMethodType());
        }

    }

    public static class RestMethodFactory {
        public static RestMethod create(RequestMethod requestMethod) {
            switch (requestMethod) {
            case GET:
                return new GetMethod();
            case POST:
                return new PostMethod();
            case DELETE:
                return new DeleteMethod();
            case PUT:
                return new PutMethod();
            default:
                throw new IllegalArgumentException("Unsupported Method: " + requestMethod.toString());
            }
        }
    }

    public static interface OnRequestFinishListener {
        void onRequestFinish(RequestMethod method, int responseCode, String message, String response);

        void onRequestFinishWithError(Exception e);
    }

    protected OnRequestFinishListener onRequestFinishListener;

    private Handler mHandler;

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

    private String url;

    public RestClient(String url) {
        init(url);
    }

    public RestClient(String url, Handler handler) {
        mHandler = handler;
        init(url);
    }

    private void init(String url) {
        this.url = url;
        params = new ArrayList<NameValuePair>();
        headers = new ArrayList<NameValuePair>();
    }

    public void setOnRequestFinishListener(OnRequestFinishListener onRequestFinishListener) {
        this.onRequestFinishListener = onRequestFinishListener;
    }

    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 boolean execute(RequestMethod method) {
        try {
            RestMethodFactory.create(method).executeRequest(this);
            return true;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return false;
    }

    private void addHeaders(AbstractHttpMessage request) {
        for (NameValuePair h : headers) {
            request.addHeader(h.getName(), h.getValue());
        }
    }

    private void executeRequest(final HttpUriRequest request, final String url, final RequestMethod method) {

        if (mHandler != null) {
            new Thread(new Runnable() {
                public void run() {
                    mExecuteRequest = new AsyncExecuteRequest(mHandler, onRequestFinishListener);
                    mExecuteRequest.execute(request, url, method);
                }
            }).start();
        } else {
            mExecuteRequest = new ExecuteRequest();
            mExecuteRequest.execute(request, url, method);
        }
    }

    public String getResponse() {
        return mExecuteRequest.getResponse();
    }

    public int getResponseCode() {
        return mExecuteRequest.getResponseCode();
    }

    public String getMessage() {
        return mExecuteRequest.getMessage();
    }

    private static String convertStreamToString(InputStream is) {

        BufferedReader reader = new BufferedReader(new InputStreamReader(is), 8192);
        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();
    }
}