luki.x.net.XNetEngine.java Source code

Java tutorial

Introduction

Here is the source code for luki.x.net.XNetEngine.java

Source

/**
 * Copyright (C) 2014 Luki(liulongke@gmail.com)
 *
 * 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 luki.x.net;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;

import luki.x.base.INetEngine;
import luki.x.base.XLog;
import luki.x.task.TaskConfig;

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
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.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.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import android.accounts.NetworkErrorException;
import android.text.TextUtils;

/**
 * XNetEngine
 * 
 * @author Luki
 */
public class XNetEngine implements INetEngine {
    private static final String TAG = XNetEngine.class.getSimpleName();

    private static HttpParams httpParams = new BasicHttpParams();

    private static int DEFAULT_SOCKET_TIMEOUT = 15 * 1000;
    private static final int DEFAULT_HOST_CONNECTIONS = 15 * 1000;
    private static final int DEFAULT_MAX_CONNECTIONS = 10;

    private static final String charSet = "UTF-8";

    private static HttpClient httpClient;
    // Proxy mProxy = null;
    private int RETRY_TIMES = 2;

    private TaskConfig config;

    public XNetEngine() {
        setDefaultHostnameVerifier();
    }

    public void setHttpConfig(TaskConfig config) {
        this.config = config;
        DEFAULT_SOCKET_TIMEOUT = config.timeOut;
        RETRY_TIMES = config.retryTimes;
    }

    /**
     * GET ?
     * 
     * @param url
     * @return
     */
    public String get(String url) throws Exception {
        if (TextUtils.isEmpty(url)) {
            XLog.i(TAG, "GET-URL is Null");
            return "";
        } else
            XLog.v(TAG, url);
        HttpGet httpGet = new HttpGet(url);
        Header[] headers = config.requestHeaders;
        if (headers != null) {
            httpGet.setHeaders(headers);
        }
        String result = null;
        HttpClient httpClient = null;
        int time = 0;
        do {
            try {
                httpClient = getHttpClient();
                InputStream in = getHttpInputStream(httpClient, httpGet);
                ByteArrayOutputStream os = new ByteArrayOutputStream();
                byte[] buff = new byte[1024];
                int len = -1;
                while ((len = in.read(buff)) != -1) {
                    os.write(buff, 0, len);
                }
                in.close();
                byte[] contentByteArray = os.toByteArray();
                os.close();
                result = new String(contentByteArray);
                time = 3;
            } catch (Exception e) {
                time++;
                if (time < RETRY_TIMES) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e1) {
                    }
                    continue;
                }
                throw e;
            } finally {
                // 
                httpClient = null;
                if (time >= RETRY_TIMES) {
                    try {
                        httpGet.abort();
                    } catch (Exception e) {
                    }
                }
            }
        } while (time < RETRY_TIMES);
        return result;
    }

    /**
     * POST ?
     * 
     * @param requestUrl
     * @return
     * @throws IOException
     */

    public String post(String serviceUrl, List<NameValuePair> params) throws Exception {
        HttpPost httpPost = new HttpPost(serviceUrl);

        httpPost.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
        Header[] headers = config.requestHeaders;
        if (headers != null) {
            httpPost.setHeaders(headers);
        }
        HttpClient httpClient = null;
        String result = null;
        HttpResponse httpResponse = null;
        int time = 0;
        do {
            try {
                httpClient = getHttpClient();
                httpResponse = httpClient.execute(httpPost);
                result = EntityUtils.toString(httpResponse.getEntity());
                time = 3;
            } catch (Exception e) {
                time++;
                XLog.w(TAG, "times:%d, %s", time, e.toString());
                if (time < RETRY_TIMES) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e1) {
                    }
                    continue;
                }
                throw e;
            } finally {
                // 
                httpClient = null;
                httpResponse = null;
                if (time >= RETRY_TIMES) {
                    try {
                        httpPost.abort();
                    } catch (Exception e) {
                    }
                }
            }
        } while (time < RETRY_TIMES);
        return result;
    }

    /**
     *  IS
     * 
     * @param url
     * @return
     * @throws Exception
     */
    public InputStream getHttpInputStream(String url) throws Exception {
        HttpGet httpGet = new HttpGet(url);//
        HttpClient httpClient = getHttpClient();
        return getHttpInputStream(httpClient, httpGet);
    }

    /**
     * getHttpClient
     * 
     * @return
     */
    private HttpClient getHttpClient() {
        // ?
        // httpParams.setParameter(ConnRoutePNames.DEFAULT_PROXY, new HttpHost("", 0));
        // httpParams.removeParameter(ConnRoutePNames.DEFAULT_PROXY);
        if (httpClient == null) {
            // timeout: get connections from connection pool
            ConnManagerParams.setTimeout(httpParams, 1000);
            // timeout: connect to the server
            HttpConnectionParams.setConnectionTimeout(httpParams, DEFAULT_SOCKET_TIMEOUT);
            // timeout: transfer data from server
            HttpConnectionParams.setSoTimeout(httpParams, DEFAULT_SOCKET_TIMEOUT);

            // set max connections per host
            ConnManagerParams.setMaxConnectionsPerRoute(httpParams, new ConnPerRouteBean(DEFAULT_HOST_CONNECTIONS));
            // set max total connections
            ConnManagerParams.setMaxTotalConnections(httpParams, DEFAULT_MAX_CONNECTIONS);

            // use expect-continue handshake
            HttpProtocolParams.setUseExpectContinue(httpParams, true);

            HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1);
            HttpProtocolParams.setContentCharset(httpParams, charSet);
            // disable Nagle algorithm
            HttpConnectionParams.setTcpNoDelay(httpParams, true);

            // scheme: http and https
            SchemeRegistry schemeRegistry = new SchemeRegistry();
            schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
            schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));

            ClientConnectionManager manager = new ThreadSafeClientConnManager(httpParams, schemeRegistry);
            httpClient = new DefaultHttpClient(manager, httpParams);
        }

        return httpClient;
    }

    private InputStream getHttpInputStream(HttpClient httpClient, HttpGet httpGet) throws Exception {
        HttpResponse httpResponse = httpClient.execute(httpGet);
        int statusCode = httpResponse.getStatusLine().getStatusCode();
        if (statusCode != HttpStatus.SC_OK) {
            throw new NetworkErrorException("statusCode != HttpStatus.SC_OK");
        }
        InputStream in = httpResponse.getEntity().getContent();
        return in;
    }

    private void setDefaultHostnameVerifier() {
        HostnameVerifier hv = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };
        HttpsURLConnection.setDefaultHostnameVerifier(hv);
    }
}