package com.aiyou.utils.http; import java.io.IOException; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import javax.net.ssl.SSLHandshakeException; import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; import org.apache.http.NoHttpResponseException; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.ClientProtocolException; 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.conn.ClientConnectionManager; import org.apache.http.conn.params.ConnManagerParams; 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.BasicCredentialsProvider; 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.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.text.TextUtils; import com.aiyou.bbs.utils.BBSManager; import com.aiyou.utils.logcat.Logcat; public class HttpManager { private static final String TAG = HttpManager.class.getSimpleName(); public static final String CHARSET = HTTP.UTF_8; private static final int POOL_TIMEOUT = 10 * 1000;// 设置连接池超时 private static final int CONNECT_TIMEOUT = 10 * 1000; private static final int READ_TIMEOUT = 10 * 1000; private static HttpManager mInstance; private ClientConnectionManager mConnMgr = null; private HttpParams mParams = null; private HttpRequestRetryHandler mRequestRetryHandler = null; private ResponseHandler<byte[]> mResponseHandler; private ConcurrentHashSet<CustomHttp> mConnSet = new ConcurrentHashSet<>(); private HttpManager(Context context) { } public static HttpManager getInstance(Context context) { if (mInstance == null) { synchronized (HttpManager.class) { if (mInstance == null) { mInstance = new HttpManager(context); } } } return mInstance; } public String getHttp(Context context, String netUrl) { byte[] data = getHttpByte(context, netUrl); if (data == null) { return null; } return new String(data); } public byte[] getHttpByte(Context context, String netUrl) { Map<String, String> header = new HashMap<>(); header.put("referer", BBSManager.BBS_URL); return getHttpByte(context, netUrl, header); } public byte[] getHttpByte(Context context, String netUrl, Map<String, String> header) { if (TextUtils.isEmpty(netUrl)) { return null; } byte[] result = null; HttpGet hg; try { hg = new HttpGet(netUrl); } catch (IllegalArgumentException e) { e.printStackTrace(); return null; } if (header != null && !header.isEmpty()) { Set<String> keySet = header.keySet(); for (String key : keySet) { hg.setHeader(key, header.get(key)); } } CustomHttp http = new CustomHttp(context, hg); mConnSet.add(http); try { result = getHttpClient(context).execute(hg, getResponseHandler()); } catch (ClientProtocolException e) { Logcat.e(TAG, "getHttpByte ClientProtocolException:" + e.getMessage()); } catch (IOException e) { Logcat.e(TAG, "getHttpByte IOException:" + e.getMessage()); } catch (Exception e) { Logcat.e(TAG, "getHttpByte Exception:" + e.getMessage()); } finally { mConnSet.remove(http); } return result; } public String postHttp(Context context, String netUrl, HttpEntity entity) { Map<String, String> header = new HashMap<>(); header.put("referer", BBSManager.BBS_URL); return postHttp(context, netUrl, entity, header); } public String postHttp(Context context, String netUrl, HttpEntity entity, Map<String, String> header) { if (TextUtils.isEmpty(netUrl)) { return null; } String result = null; HttpPost hp; try { hp = new HttpPost(netUrl); } catch (IllegalArgumentException e) { e.printStackTrace(); return null; } if (header != null && !header.isEmpty()) { Set<String> keySet = header.keySet(); for (String key : keySet) { hp.setHeader(key, header.get(key)); } } CustomHttp http = new CustomHttp(context, hp); mConnSet.add(http); // 把参数设置到httpPost实体 if (null != entity) { hp.setEntity(entity); } DefaultHttpClient client = getHttpClient(context); client.setHttpRequestRetryHandler(getHttpRequestRetryHandler()); try { byte[] data = client.execute(hp, getResponseHandler()); if (data == null) { result = null; } else { result = new String(data); } } catch (ClientProtocolException e) { Logcat.e(TAG, "postHttp ClientProtocolException:" + e.getMessage()); } catch (IOException e) { Logcat.e(TAG, "postHttp IOException:" + e.getMessage()); } catch (Exception e) { Logcat.e(TAG, "getHttpByte Exception:" + e.getMessage()); } finally { mConnSet.remove(http); } return result; } /** * 程序退出时调用,调用此函数无需再调用disconnect、disconnectAll函数 */ public void release() { if (mConnMgr != null) { new Thread() { @Override public void run() { mConnMgr.shutdown(); mConnMgr = null; } }.start(); } } /** * 中断某一个Context开启的所有网络连接 * * @param context */ public synchronized void disconnect(Context context) { if (mConnSet.isEmpty()) { return; } String tag = context.getClass().getSimpleName(); Set<CustomHttp> temp = new HashSet<>(); for (CustomHttp http : mConnSet) { if (tag.equals(http.getTag())) { http.getHttp().abort(); temp.add(http); } } if (!temp.isEmpty()) { mConnSet.removeAll(temp); } } /** * 中断所有网络连接 */ public synchronized void disconnectAll() { if (mConnSet.isEmpty()) { return; } for (CustomHttp http : mConnSet) { http.getHttp().abort(); } mConnSet.clear(); } // /** // * 将InputStream中的内容读取为比特数组 // * // * @param is // * @return // */ // public static byte[] parseStream(InputStream is) { // if (is == null) { // return null; // } // byte[] result = new byte[1024]; // // int length = -1; // ByteArrayOutputStream byteArrayOutputStream = new // ByteArrayOutputStream(); // try { // while ((length = is.read(result)) != -1) { // byteArrayOutputStream.write(result, 0, length); // } // result = byteArrayOutputStream.toByteArray(); // } catch (IOException e) { // Logcat.e(TAG, "parseStream IOException:" + e.getMessage()); // result = null; // } finally { // FileManager.close(byteArrayOutputStream); // } // return result; // } private HttpRequestRetryHandler getHttpRequestRetryHandler() { if (mRequestRetryHandler != null) { return mRequestRetryHandler; } mRequestRetryHandler = new HttpRequestRetryHandler() { // 自定义的恢复策略 public synchronized boolean retryRequest(IOException exception, int executionCount, HttpContext context) { // 设置恢复策略,在发生异常时候将自动重试3次 if (executionCount > 3) { // 超过最大次数则不需要重试 return false; } if (exception instanceof NoHttpResponseException) { // 服务停掉则不重新连接 return false; } if (exception instanceof SSLHandshakeException) { // SSL异常不需要重试 return false; } HttpRequest request = (HttpRequest) context .getAttribute(ExecutionContext.HTTP_REQUEST); boolean idempotent = (request instanceof HttpEntityEnclosingRequest); return !idempotent; } }; return mRequestRetryHandler; } private ResponseHandler<byte[]> getResponseHandler() { if (mResponseHandler != null) { return mResponseHandler; } mResponseHandler = new ResponseHandler<byte[]>() { public byte[] handleResponse(HttpResponse response) throws IOException { HttpEntity entity = response.getEntity(); if (entity != null) { return EntityUtils.toByteArray(entity); } else { return null; } } }; return mResponseHandler; } /** * 获取HttpClient对象 * * @param context * @return */ private DefaultHttpClient getHttpClient(Context context) { HttpParams httpParams = getHttpParams(); // 使用线程安全的连接管理来创建HttpClient if (mConnMgr == null) { SchemeRegistry schReg = new SchemeRegistry(); schReg.register(new Scheme("http", PlainSocketFactory .getSocketFactory(), 80)); schReg.register(new Scheme("https", SSLSocketFactory .getSocketFactory(), 443)); mConnMgr = new ThreadSafeClientConnManager(httpParams, schReg); } DefaultHttpClient client = new DefaultHttpClient(mConnMgr, httpParams); // 身份验证 BBSManager bbsMgr = BBSManager.getInstance(context); UsernamePasswordCredentials upc = new UsernamePasswordCredentials( bbsMgr.getUserId(), bbsMgr.getUserPassword()); // 这一句使用用户名密码建立了一个数据 AuthScope as = new AuthScope(null, -1); BasicCredentialsProvider bcp = new BasicCredentialsProvider(); bcp.setCredentials(as, upc); client.setCredentialsProvider(bcp); return client; } private HttpParams getHttpParams() { if (mParams != null) { return mParams; } // 设置一些基本参数 mParams = new BasicHttpParams(); HttpProtocolParams.setVersion(mParams, HttpVersion.HTTP_1_1); HttpProtocolParams.setContentCharset(mParams, CHARSET); HttpProtocolParams.setUseExpectContinue(mParams, true); // HttpProtocolParams // .setUserAgent( // httpParams, // "Mozilla/5.0(Linux;U;Android 2.3.3;en-us;Nexus One Build.FRG83) " // + // "AppleWebKit/553.1(KHTML,like Gecko) Version/4.0 Mobile Safari/533.1"); // // 代理的设置 // HttpHost proxy = new HttpHost("10.60.8.20", 8080); // httpParams.setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy); /* 从连接池中取连接的超时时间 */ ConnManagerParams.setTimeout(mParams, POOL_TIMEOUT); // 设置连接池超时0秒钟 HttpConnectionParams.setConnectionTimeout(mParams, CONNECT_TIMEOUT); HttpConnectionParams.setSoTimeout(mParams, READ_TIMEOUT); // 设置等待数据超时时间0秒钟 return mParams; } }