com.micro.http.MicroHttpClient.java Source code

Java tutorial

Introduction

Here is the source code for com.micro.http.MicroHttpClient.java

Source

/*
 * Copyright (C) 2012 Chengel_HaltuD
 * 
 * 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.
 */
package com.micro.http;

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.concurrent.Executor;

import javax.net.ssl.SSLHandshakeException;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.NoHttpResponseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.params.CookiePolicy;
import org.apache.http.client.params.HttpClientParams;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.params.ConnPerRouteBean;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.scheme.SocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.ExecutionContext;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;

import android.content.Context;
import android.os.Handler;
import android.os.Message;

import com.micro.cache.MicroAppConfig;
import com.micro.http.entity.MultipartEntity;
import com.micro.http.ssl.EasySSLProtocolSocketFactory;
import com.micro.utils.A;
import com.micro.utils.F;
import com.micro.utils.L;

// TODO: Auto-generated Javadoc
/**
 * 
 * @ClassName: MicroHttpClient
 * @Description: ??Http
 * @AuthorChengel_HaltuD
 * @Date2015-5-30 ?2:51:19
 * @version V1.0
 *
 */
public class MicroHttpClient {

    /** . */
    private static Context mContext;

    /** . */
    public static Executor mExecutorService = null;

    /** ?. */
    private String encode = HTTP.UTF_8;

    /** ?. */
    private String userAgent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.43 BIDUBrowser/6.x Safari/537.31";

    private static final String HTTP_GET = "GET";
    private static final String HTTP_POST = "POST";
    private static final String USER_AGENT = "User-Agent";
    private static final String ACCEPT_ENCODING = "Accept-Encoding";

    /** CookieStore. */
    private CookieStore mCookieStore;

    /** . */
    private static final int DEFAULT_MAX_CONNECTIONS = 10;

    /** . */
    public static final int DEFAULT_SOCKET_TIMEOUT = 10000;

    /** ?. */
    private static final int DEFAULT_MAX_RETRIES = 2;

    /** ?. */
    private static final int DEFAULT_SOCKET_BUFFER_SIZE = 8192;

    /** ?. */
    protected static final int SUCCESS_MESSAGE = 0;

    /** . */
    protected static final int FAILURE_MESSAGE = 1;

    /** . */
    protected static final int FAILURE_MESSAGE_CONNECT = 2;

    /** ?. */
    protected static final int FAILURE_MESSAGE_SERVICE = 3;

    /** . */
    protected static final int START_MESSAGE = 4;

    /** ?. */
    protected static final int FINISH_MESSAGE = 5;

    /** . */
    protected static final int PROGRESS_MESSAGE = 6;

    /** ?. */
    protected static final int RETRY_MESSAGE = 7;

    /** . */
    private int mTimeout = DEFAULT_SOCKET_TIMEOUT;

    /** ?. ?HTTPSSSL*/
    private boolean mIsOpenEasySSL = true;

    /** HTTP Client*/
    private DefaultHttpClient mHttpClient = null;

    /** HTTP */
    private HttpContext mHttpContext = null;

    /**
     * ?.
     *
     * @param context the context
     */
    public MicroHttpClient(Context context) {
        mContext = context;
        mExecutorService = MicroThreadFactory.getExecutorService();
        mHttpContext = new BasicHttpContext();
    }

    /**
     * ???get.
     *
     * @param url the url
     * @param params the params
     * @param responseListener the response listener
     */
    public void get(final String url, final MicroRequestParams params,
            final MicroHttpResponseListener responseListener) {

        responseListener.setHandler(new ResponderHandler(responseListener));
        mExecutorService.execute(new Runnable() {
            public void run() {
                try {
                    doGet(url, params, responseListener);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * ???post.
     *
     * @param url the url
     * @param params the params
     * @param responseListener the response listener
     */
    public void post(final String url, final MicroRequestParams params,
            final MicroHttpResponseListener responseListener) {
        responseListener.setHandler(new ResponderHandler(responseListener));
        mExecutorService.execute(new Runnable() {
            public void run() {
                try {
                    doPost(url, params, responseListener);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * ??get.
     *
     * @param url the url
     * @param params the params
     * @param responseListener the response listener
     */
    private void doGet(String url, MicroRequestParams params, MicroHttpResponseListener responseListener) {
        try {

            responseListener.sendStartMessage();

            if (!A.isNetworkAvailable(mContext)) {
                Thread.sleep(200);
                responseListener.sendFailureMessage(MicroHttpStatus.CONNECT_FAILURE_CODE,
                        MicroAppConfig.CONNECT_EXCEPTION, new MicroAppException(MicroAppConfig.CONNECT_EXCEPTION));
                return;
            }

            //HttpGet  
            if (params != null) {
                if (url.indexOf("?") == -1) {
                    url += "?";
                }
                url += params.getParamString();
            }
            HttpGet httpGet = new HttpGet(url);
            httpGet.addHeader(USER_AGENT, userAgent);
            //
            httpGet.addHeader(ACCEPT_ENCODING, "gzip");
            //?HttpClient
            HttpClient httpClient = getHttpClient();
            //?HttpResponse
            String response = httpClient.execute(httpGet, new RedirectionResponseHandler(url, responseListener),
                    mHttpContext);
            L.I("[HTTP GET]:" + url + ",result" + response);
        } catch (Exception e) {
            e.printStackTrace();
            //???
            responseListener.sendFailureMessage(MicroHttpStatus.UNTREATED_CODE, e.getMessage(),
                    new MicroAppException(e));
        } finally {
            responseListener.sendFinishMessage();
        }
    }

    /**
     * ??post.
     *
     * @param url the url
     * @param params the params
     * @param responseListener the response listener
     */
    private void doPost(String url, MicroRequestParams params, MicroHttpResponseListener responseListener) {
        try {
            responseListener.sendStartMessage();

            if (!A.isNetworkAvailable(mContext)) {
                Thread.sleep(200);
                responseListener.sendFailureMessage(MicroHttpStatus.CONNECT_FAILURE_CODE,
                        MicroAppConfig.CONNECT_EXCEPTION, new MicroAppException(MicroAppConfig.CONNECT_EXCEPTION));
                return;
            }

            //HttpPost  
            HttpPost httpPost = new HttpPost(url);
            httpPost.addHeader(USER_AGENT, userAgent);
            //
            httpPost.addHeader(ACCEPT_ENCODING, "gzip");
            //??
            boolean isContainFile = false;
            if (params != null) {
                //NameValuePair???Post? 
                HttpEntity httpentity = params.getEntity();
                //httpRequest  
                httpPost.setEntity(httpentity);
                if (params.getFileParams().size() > 0) {
                    isContainFile = true;
                }
            }
            String response = null;
            //?HttpClient
            DefaultHttpClient httpClient = getHttpClient();
            if (isContainFile) {
                httpPost.addHeader("connection", "keep-alive");
                httpPost.addHeader("Content-Type", "multipart/form-data; boundary=" + params.boundaryString());
                L.I("[HTTP POST]:" + url + ",?!");
            }
            //?HttpResponse
            response = httpClient.execute(httpPost, new RedirectionResponseHandler(url, responseListener),
                    mHttpContext);
            L.I("request" + url + ",result" + response);

        } catch (Exception e) {
            e.printStackTrace();
            L.I("[HTTP POST]:" + url + ",error" + e.getMessage());
            //???
            responseListener.sendFailureMessage(MicroHttpStatus.UNTREATED_CODE, e.getMessage(),
                    new MicroAppException(e));
        } finally {
            responseListener.sendFinishMessage();
        }
    }

    /**
      * ?,???String,?????
      * @param url
      * @param params
      * @return
      */
    public void doRequest(final String url, final MicroRequestParams params,
            final MicroStringHttpResponseListener responseListener) {
        responseListener.setHandler(new ResponderHandler(responseListener));
        mExecutorService.execute(new Runnable() {
            public void run() {
                HttpURLConnection urlConn = null;
                try {
                    responseListener.sendStartMessage();

                    if (!A.isNetworkAvailable(mContext)) {
                        Thread.sleep(200);
                        responseListener.sendFailureMessage(MicroHttpStatus.CONNECT_FAILURE_CODE,
                                MicroAppConfig.CONNECT_EXCEPTION,
                                new MicroAppException(MicroAppConfig.CONNECT_EXCEPTION));
                        return;
                    }

                    String resultString = null;
                    URL requestUrl = new URL(url);
                    urlConn = (HttpURLConnection) requestUrl.openConnection();
                    urlConn.setRequestMethod("POST");
                    urlConn.setConnectTimeout(mTimeout);
                    urlConn.setReadTimeout(mTimeout);
                    urlConn.setDoOutput(true);

                    if (params != null) {
                        urlConn.setRequestProperty("connection", "keep-alive");
                        urlConn.setRequestProperty("Content-Type",
                                "multipart/form-data; boundary=" + params.boundaryString());
                        MultipartEntity reqEntity = params.getMultiPart();
                        reqEntity.writeTo(urlConn.getOutputStream());
                    } else {
                        urlConn.connect();
                    }

                    if (urlConn.getResponseCode() == HttpStatus.SC_OK) {
                        resultString = readString(urlConn.getInputStream());
                    } else {
                        resultString = readString(urlConn.getErrorStream());
                    }
                    resultString = URLEncoder.encode(resultString, encode);
                    urlConn.getInputStream().close();
                    responseListener.sendSuccessMessage(MicroHttpStatus.SUCCESS_CODE, resultString);
                } catch (Exception e) {
                    e.printStackTrace();
                    L.I("[HTTP POST]:" + url + ",error" + e.getMessage());
                    //???
                    responseListener.sendFailureMessage(MicroHttpStatus.UNTREATED_CODE, e.getMessage(),
                            new MicroAppException(e));
                } finally {
                    if (urlConn != null)
                        urlConn.disconnect();

                    responseListener.sendFinishMessage();
                }
            }
        });
    }

    /**
     * ??.
     * 
     * @param context the context
     * @param entity the entity
     * @param name the name
     * @param responseListener the response listener
     */
    public void writeResponseData(Context context, HttpEntity entity, String name,
            MicroFileHttpResponseListener responseListener) {

        if (entity == null) {
            return;
        }

        if (responseListener.getFile() == null) {
            //
            responseListener.setFile(context, name);
        }

        InputStream inStream = null;
        FileOutputStream outStream = null;
        try {
            inStream = entity.getContent();
            long contentLength = entity.getContentLength();
            outStream = new FileOutputStream(responseListener.getFile());
            if (inStream != null) {

                byte[] tmp = new byte[4096];
                int l, count = 0;
                while ((l = inStream.read(tmp)) != -1 && !Thread.currentThread().isInterrupted()) {
                    count += l;
                    outStream.write(tmp, 0, l);
                    responseListener.sendProgressMessage(count, (int) contentLength);
                }
            }
            responseListener.sendSuccessMessage(200);
        } catch (Exception e) {
            e.printStackTrace();
            //???
            responseListener.sendFailureMessage(MicroHttpStatus.RESPONSE_TIMEOUT_CODE,
                    MicroAppConfig.SOCKET_TIMEOUT_EXCEPTION, e);
        } finally {
            try {
                if (inStream != null) {
                    inStream.close();
                }
                if (outStream != null) {
                    outStream.flush();
                    outStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * ???.
     *
     * @param entity the entity
     * @param responseListener the response listener
     */
    public void readResponseData(HttpEntity entity, MicroBinaryHttpResponseListener responseListener) {

        if (entity == null) {
            return;
        }

        InputStream inStream = null;
        ByteArrayOutputStream outSteam = null;

        try {
            inStream = entity.getContent();
            outSteam = new ByteArrayOutputStream();
            long contentLength = entity.getContentLength();
            if (inStream != null) {
                int l, count = 0;
                byte[] tmp = new byte[4096];
                while ((l = inStream.read(tmp)) != -1) {
                    count += l;
                    outSteam.write(tmp, 0, l);
                    responseListener.sendProgressMessage(count, (int) contentLength);

                }
            }
            responseListener.sendSuccessMessage(HttpStatus.SC_OK, outSteam.toByteArray());
        } catch (Exception e) {
            e.printStackTrace();
            //???
            responseListener.sendFailureMessage(MicroHttpStatus.RESPONSE_TIMEOUT_CODE,
                    MicroAppConfig.SOCKET_TIMEOUT_EXCEPTION, e);
        } finally {
            try {
                if (inStream != null) {
                    inStream.close();
                }
                if (outSteam != null) {
                    outSteam.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * ??.
     *
     * @param timeout 
     */
    public void setTimeout(int timeout) {
        this.mTimeout = timeout;
    }

    /**
     *  2012 amsoft.cn
     * ??ResponderHandler.java 
     * ??
     *
     * @author 
     * @version v1.0
     * @date2013-11-13 ?3:22:30
     */
    private static class ResponderHandler extends Handler {

        /** ??. */
        private Object[] response;

        /** ???. */
        private MicroHttpResponseListener responseListener;

        /**
         * ???.
         *
         * @param responseListener the response listener
         */
        public ResponderHandler(MicroHttpResponseListener responseListener) {
            this.responseListener = responseListener;
        }

        /* (non-Javadoc)
         * @see android.os.Handler#handleMessage(android.os.Message)
         */
        @Override
        public void handleMessage(Message msg) {

            switch (msg.what) {

            case SUCCESS_MESSAGE:
                response = (Object[]) msg.obj;

                if (response != null) {
                    if (responseListener instanceof MicroStringHttpResponseListener) {
                        if (response.length >= 2) {
                            ((MicroStringHttpResponseListener) responseListener).onSuccess((Integer) response[0],
                                    (String) response[1]);
                        } else {
                            L.E("SUCCESS_MESSAGE " + MicroAppConfig.MISSING_PARAMETERS);
                        }

                    } else if (responseListener instanceof MicroBinaryHttpResponseListener) {
                        if (response.length >= 2) {
                            ((MicroBinaryHttpResponseListener) responseListener).onSuccess((Integer) response[0],
                                    (byte[]) response[1]);
                        } else {
                            L.E("SUCCESS_MESSAGE " + MicroAppConfig.MISSING_PARAMETERS);
                        }
                    } else if (responseListener instanceof MicroFileHttpResponseListener) {

                        if (response.length >= 1) {
                            MicroFileHttpResponseListener mAbFileHttpResponseListener = ((MicroFileHttpResponseListener) responseListener);
                            mAbFileHttpResponseListener.onSuccess((Integer) response[0],
                                    mAbFileHttpResponseListener.getFile());
                        } else {
                            L.E("SUCCESS_MESSAGE " + MicroAppConfig.MISSING_PARAMETERS);
                        }

                    }
                }
                break;
            case FAILURE_MESSAGE:
                response = (Object[]) msg.obj;
                if (response != null && response.length >= 3) {
                    //????
                    MicroAppException exception = new MicroAppException((Exception) response[2]);
                    responseListener.onFailure((Integer) response[0], (String) response[1], exception);
                } else {
                    L.E("FAILURE_MESSAGE " + MicroAppConfig.MISSING_PARAMETERS);
                }
                break;
            case START_MESSAGE:
                responseListener.onStart();
                break;
            case FINISH_MESSAGE:
                responseListener.onFinish();
                break;
            case PROGRESS_MESSAGE:
                response = (Object[]) msg.obj;
                if (response != null && response.length >= 2) {
                    responseListener.onProgress((Long) response[0], (Long) response[1]);
                } else {
                    L.E("PROGRESS_MESSAGE " + MicroAppConfig.MISSING_PARAMETERS);
                }
                break;
            case RETRY_MESSAGE:
                responseListener.onRetry();
                break;
            default:
                break;
            }
        }

    }

    /**
     * HTTP??
     * @return
     */
    public BasicHttpParams getHttpParams() {

        BasicHttpParams httpParams = new BasicHttpParams();

        // ?
        ConnPerRouteBean connPerRoute = new ConnPerRouteBean(30);
        ConnManagerParams.setMaxConnectionsPerRoute(httpParams, connPerRoute);
        HttpConnectionParams.setStaleCheckingEnabled(httpParams, false);
        // ?1
        ConnManagerParams.setTimeout(httpParams, mTimeout);
        ConnManagerParams.setMaxConnectionsPerRoute(httpParams, new ConnPerRouteBean(DEFAULT_MAX_CONNECTIONS));
        ConnManagerParams.setMaxTotalConnections(httpParams, DEFAULT_MAX_CONNECTIONS);
        // ??
        HttpConnectionParams.setSoTimeout(httpParams, mTimeout);
        HttpConnectionParams.setConnectionTimeout(httpParams, mTimeout);
        HttpConnectionParams.setTcpNoDelay(httpParams, true);
        HttpConnectionParams.setSocketBufferSize(httpParams, DEFAULT_SOCKET_BUFFER_SIZE);

        HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1);
        HttpProtocolParams.setUserAgent(httpParams, userAgent);
        //?
        HttpClientParams.setRedirecting(httpParams, false);
        HttpClientParams.setCookiePolicy(httpParams, CookiePolicy.BROWSER_COMPATIBILITY);
        httpParams.setParameter(ConnRoutePNames.DEFAULT_PROXY, null);
        return httpParams;

    }

    /**
     * ?HttpClient???????AuthSSLProtocolSocketFactory
     * @return
     */
    public DefaultHttpClient getHttpClient() {

        if (mHttpClient != null) {
            return mHttpClient;
        } else {
            return createHttpClient();
        }
    }

    /**
     * ?HttpClient???????AuthSSLProtocolSocketFactory
     * @param httpParams
     * @return
     */
    public DefaultHttpClient createHttpClient() {
        BasicHttpParams httpParams = getHttpParams();
        if (mIsOpenEasySSL) {
            // ?https   SSL??
            EasySSLProtocolSocketFactory easySSLProtocolSocketFactory = new EasySSLProtocolSocketFactory();
            SchemeRegistry supportedSchemes = new SchemeRegistry();
            SocketFactory socketFactory = PlainSocketFactory.getSocketFactory();
            supportedSchemes.register(new Scheme("http", socketFactory, 80));
            supportedSchemes.register(new Scheme("https", easySSLProtocolSocketFactory, 443));
            //ThreadSafeClientConnManager???HttpClient
            ClientConnectionManager connectionManager = new ThreadSafeClientConnManager(httpParams,
                    supportedSchemes);
            //?HttpClient ThreadSafeClientConnManager
            mHttpClient = new DefaultHttpClient(connectionManager, httpParams);
        } else {
            //HttpClient
            mHttpClient = new DefaultHttpClient(httpParams);
        }
        //?
        mHttpClient.setHttpRequestRetryHandler(mRequestRetryHandler);
        mHttpClient.setCookieStore(mCookieStore);
        return mHttpClient;
    }

    /**
     * ?ssl ??
     */
    public boolean isOpenEasySSL() {
        return mIsOpenEasySSL;
    }

    /**
     * ssl ??
     * @param isOpenEasySSL
     */
    public void setOpenEasySSL(boolean isOpenEasySSL) {
        this.mIsOpenEasySSL = isOpenEasySSL;
    }

    /**
     * ResponseHandler???,???
     */
    private class RedirectionResponseHandler implements ResponseHandler<String> {

        private MicroHttpResponseListener mResponseListener = null;
        private String mUrl = null;

        public RedirectionResponseHandler(String url, MicroHttpResponseListener responseListener) {
            super();
            this.mUrl = url;
            this.mResponseListener = responseListener;
        }

        @Override
        public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
            HttpUriRequest request = (HttpUriRequest) mHttpContext.getAttribute(ExecutionContext.HTTP_REQUEST);
            //?  
            int statusCode = response.getStatusLine().getStatusCode();
            HttpEntity entity = response.getEntity();
            String responseBody = null;
            //200
            if (statusCode == HttpStatus.SC_OK) {

                // ??response body
                // requestabort  
                // request.abort();  

                if (entity != null) {
                    if (mResponseListener instanceof MicroStringHttpResponseListener) {
                        //entity??,?Content has been consumed
                        //?
                        Header header = entity.getContentEncoding();
                        if (header != null) {
                            String contentEncoding = header.getValue();
                            if (contentEncoding != null) {
                                if (contentEncoding.contains("gzip")) {
                                    entity = new MicroGzipDecompressingEntity(entity);
                                }
                            }
                        }
                        String charset = EntityUtils.getContentCharSet(entity) == null ? encode
                                : EntityUtils.getContentCharSet(entity);
                        responseBody = new String(EntityUtils.toByteArray(entity), charset);

                        ((MicroStringHttpResponseListener) mResponseListener).sendSuccessMessage(statusCode,
                                responseBody);
                    } else if (mResponseListener instanceof MicroBinaryHttpResponseListener) {
                        responseBody = "Binary";
                        readResponseData(entity, ((MicroBinaryHttpResponseListener) mResponseListener));
                    } else if (mResponseListener instanceof MicroFileHttpResponseListener) {
                        //???
                        String fileName = F.getCacheFileNameFromUrl(mUrl, response);
                        writeResponseData(mContext, entity, fileName,
                                ((MicroFileHttpResponseListener) mResponseListener));
                    }
                    //?!!!
                    try {
                        entity.consumeContent();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return responseBody;
                }

            }
            //301 302??
            else if (statusCode == HttpStatus.SC_MOVED_TEMPORARILY
                    || statusCode == HttpStatus.SC_MOVED_PERMANENTLY) {
                // ???
                Header locationHeader = response.getLastHeader("location");
                String location = locationHeader.getValue();
                if (request.getMethod().equalsIgnoreCase(HTTP_POST)) {
                    doPost(location, null, mResponseListener);
                } else if (request.getMethod().equalsIgnoreCase(HTTP_GET)) {
                    doGet(location, null, mResponseListener);
                }
            } else if (statusCode == HttpStatus.SC_NOT_FOUND) {
                //404
                mResponseListener.sendFailureMessage(statusCode, MicroAppConfig.NOT_FOUND_EXCEPTION,
                        new MicroAppException(MicroAppConfig.NOT_FOUND_EXCEPTION));
            } else if (statusCode == HttpStatus.SC_FORBIDDEN) {
                //403
                mResponseListener.sendFailureMessage(statusCode, MicroAppConfig.FORBIDDEN_EXCEPTION,
                        new MicroAppException(MicroAppConfig.FORBIDDEN_EXCEPTION));
            } else {
                mResponseListener.sendFailureMessage(statusCode, MicroAppConfig.REMOTE_SERVICE_EXCEPTION,
                        new MicroAppException(MicroAppConfig.REMOTE_SERVICE_EXCEPTION));
            }
            return null;
        }
    }

    /**
     * ??
     */
    private HttpRequestRetryHandler mRequestRetryHandler = new HttpRequestRetryHandler() {

        // ??
        public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
            // ????DEFAULT_MAX_RETRIES
            if (executionCount >= DEFAULT_MAX_RETRIES) {
                // ???
                L.D("???");
                return false;
            }
            if (exception instanceof NoHttpResponseException) {
                // ??
                L.D("??");
                return true;
            }
            if (exception instanceof SSLHandshakeException) {
                // SSL???
                L.D("ssl  ??");
                return false;
            }
            HttpRequest request = (HttpRequest) context.getAttribute(ExecutionContext.HTTP_REQUEST);
            boolean idempotent = (request instanceof HttpEntityEnclosingRequest);
            if (!idempotent) {
                // ?
                L.D("?");
                return true;
            }
            if (exception != null) {
                return true;
            }
            return false;
        }
    };

    private String readString(InputStream is) {
        StringBuffer rst = new StringBuffer();

        byte[] buffer = new byte[1048576];
        int len = 0;

        try {
            while ((len = is.read(buffer)) > 0)
                for (int i = 0; i < len; ++i)
                    rst.append((char) buffer[i]);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return rst.toString();
    }

    /**
     * ??
     * @return
     */
    public String getUserAgent() {
        return userAgent;
    }

    /**
     * ?
     * @param userAgent
     */
    public void setUserAgent(String userAgent) {
        this.userAgent = userAgent;
    }

    /**
      * ??
      * @return
      */
    public String getEncode() {
        return encode;
    }

    /**
     * ?
     * @param encode
     */
    public void setEncode(String encode) {
        this.encode = encode;
    }

    /**
     * HttpClient
     */
    public void shutdown() {
        if (mHttpClient != null && mHttpClient.getConnectionManager() != null) {
            mHttpClient.getConnectionManager().shutdown();
        }
    }

    public CookieStore getCookieStore() {
        if (mHttpClient != null) {
            mCookieStore = mHttpClient.getCookieStore();
        }
        return mCookieStore;
    }

    public void setCookieStore(CookieStore cookieStore) {
        this.mCookieStore = cookieStore;
    }

}