cn.com.zzwfang.http.HttpClient.java Source code

Java tutorial

Introduction

Here is the source code for cn.com.zzwfang.http.HttpClient.java

Source

/*
 * Copyright (c) 2013-2014 Soo
 *
 * 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 cn.com.zzwfang.http;

import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.HashSet;
import java.util.Iterator;

import javax.net.ssl.SSLException;

import org.apache.http.HttpResponse;
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.HttpRequestRetryHandler;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.client.params.CookiePolicy;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.params.ConnPerRouteBean;
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.ssl.SSLSocketFactory;
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.HttpContext;
import org.apache.http.protocol.SyncBasicHttpContext;

import android.content.Context;
import android.os.SystemClock;
import android.util.Log;

/**
 * 
 * Apache DefaultHttpClient ?
 * 
 * ?Http  request()
 * 
 *  ? Apache DefaultHttpClient ?
 * 
 * 
 * @author Soo
 */
public class HttpClient implements HttpClientInterface {

    private static final int DEFAULT_SOCKET_TIMEOUT = 30 * 1000;

    private static final int DEFAULT_MAX_CONNECTIONS = 10;

    private static final int DEFAULT_TOTAL_CONNECTIONS = 10;

    private static final int DEFAULT_SOCKET_BUFFER_SIZE = 8192;

    private static final int DEFAULT_MAX_RETRIES = 5;

    private static HttpContext httpContext;

    private static DefaultHttpClient httpClient;

    private int totalConnections = DEFAULT_TOTAL_CONNECTIONS;

    private int maxConnections = DEFAULT_MAX_CONNECTIONS;

    private int socketTimeout = DEFAULT_SOCKET_TIMEOUT;

    private String userAgent = "USERAGENT_ASP";

    /**
     * Cookie
     */
    //   private PersistentCookieStore cookieStore;

    public HttpClient(Context context) {
        if (httpClient != null) {
            return;
        }
        //      Log.i("--->", "HttpClient ?httpClient-------------");
        BasicHttpParams httpParams = new BasicHttpParams();
        ConnManagerParams.setTimeout(httpParams, socketTimeout);
        ConnManagerParams.setMaxConnectionsPerRoute(httpParams, new ConnPerRouteBean(maxConnections));
        ConnManagerParams.setMaxTotalConnections(httpParams, totalConnections);

        HttpConnectionParams.setConnectionTimeout(httpParams, socketTimeout);
        HttpConnectionParams.setSoTimeout(httpParams, socketTimeout);
        HttpConnectionParams.setTcpNoDelay(httpParams, true);
        HttpConnectionParams.setSocketBufferSize(httpParams, DEFAULT_SOCKET_BUFFER_SIZE);

        HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1);
        HttpProtocolParams.setUserAgent(httpParams, userAgent);

        SchemeRegistry schemeRegistry = new SchemeRegistry();
        schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
        ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(httpParams, schemeRegistry);

        httpParams.setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);

        httpContext = new SyncBasicHttpContext(new BasicHttpContext());
        httpClient = new DefaultHttpClient(cm, httpParams);
        httpClient.setHttpRequestRetryHandler(new InnerRetryHandler(DEFAULT_MAX_RETRIES));
        //      cookieStore = new PersistentCookieStore(context);
        //      httpContext.setAttribute("http.cookie-store", cookieStore);
        //      httpClient.setCookieStore(cookieStore);

    }

    public HttpContext getHttpContext() {
        return httpContext;
    }

    public void setHttpContext(HttpContext httpContext) {
        this.httpContext = httpContext;
    }

    public void setCookieStore(CookieStore cookieStore) {
        httpContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
    }

    private static class InnerRetryHandler implements HttpRequestRetryHandler {

        private static final int RETRY_SLEEP_TIME_MILLIS = 1500;
        private static HashSet<Class<?>> exceptionWhitelist = new HashSet<Class<?>>();
        private static HashSet<Class<?>> exceptionBlacklist = new HashSet<Class<?>>();

        static {
            // Retry if the server dropped connection on us
            exceptionWhitelist.add(NoHttpResponseException.class);
            // retry-this, since it may happens as part of a Wi-Fi to 3G
            // failover
            exceptionWhitelist.add(UnknownHostException.class);
            // retry-this, since it may happens as part of a Wi-Fi to 3G
            // failover
            exceptionWhitelist.add(SocketException.class);
            // never retry timeouts
            exceptionBlacklist.add(InterruptedIOException.class);
            // never retry SSL handshake failures
            exceptionBlacklist.add(SSLException.class);
        }

        private int maxRetries;

        public InnerRetryHandler(int maxRetries) {
            this.maxRetries = maxRetries;
        }

        @Override
        public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
            boolean retry = true;

            Boolean b = (Boolean) context.getAttribute(ExecutionContext.HTTP_REQ_SENT);
            boolean sent = (b != null && b.booleanValue());

            if (executionCount > maxRetries) {
                // Do not retry if over max retry count
                retry = false;
            } else if (isInList(exceptionBlacklist, exception)) {
                // immediately cancel retry if the error is blacklisted
                retry = false;
            } else if (isInList(exceptionWhitelist, exception)) {
                // immediately retry if error is whitelisted
                retry = true;
            } else if (!sent) {
                // for most other errors, retry only if request hasn't been
                // fully sent yet
                retry = true;
            }

            if (retry) {
                // resend all idempotent requests
                HttpUriRequest currentReq = (HttpUriRequest) context.getAttribute(ExecutionContext.HTTP_REQUEST);
                String requestType = currentReq.getMethod();
                retry = !requestType.equals("POST");
            }

            if (retry) {
                SystemClock.sleep(RETRY_SLEEP_TIME_MILLIS);
            } else {
                exception.printStackTrace();
            }

            return retry;
        }

        protected boolean isInList(HashSet<Class<?>> list, Throwable error) {
            Iterator<Class<?>> itr = list.iterator();
            while (itr.hasNext()) {
                if (itr.next().isInstance(error)) {
                    return true;
                }
            }
            return false;
        }
    }

    @Override
    public HttpResponse request(HttpUriRequest httpUriRequest) {
        if (httpUriRequest == null || httpClient == null) {
            return null;
        }
        HttpResponse httpResponse = null;
        try {
            httpResponse = httpClient.execute(httpUriRequest);
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return httpResponse;
    }

    public DefaultHttpClient getDefaultHttpClient() {
        return httpClient;
    }

}