package com.salama.android.developer.util.http; import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; import java.util.zip.GZIPInputStream; import org.apache.http.HeaderElement; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; 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.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.client.utils.URLEncodedUtils; 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.entity.mime.HttpMultipartMode; import org.apache.http.entity.mime.MultipartEntity; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.entity.mime.content.StringBody; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; import org.apache.http.message.BasicNameValuePair; 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 android.os.Build; import com.salama.android.developer.SalamaAppService; import com.salama.android.util.SSLog; import com.salama.android.util.http.MultiPartFile; import com.salama.android.util.http.EasySSLSocketFactory; public class SalamaHttpClientUtil { public static final String DEFAULT_CHARSET = HTTP.UTF_8; public static final Charset DefaultCharset = Charset.forName(DEFAULT_CHARSET); public static final int DEFAULT_CONNECTION_POOL_TIMEOUT_MS = 10000; public static final int DEFAULT_CONNECTION_TIMEOUT_MS = 10000; public static final int DEFAULT_REQUEST_TIMEOUT_MS = 30000; private static final int RESPONSE_STATUS_SUCCESS = 200; //Salama Easy App在AppToken认证不通过的时候,采用code 401来表征 private final static int HTTP_STATUS_CODE_APP_TOKEN_INVALID = 405; private static ClientConnectionManager connectionManager; private static HttpParams httpParams = new BasicHttpParams(); //2K byte private static final int TEMP_BUFFER_DEFAULT_LENGTH = 2048; public static void initHttpParams( int connectionPooltimeoutMS, int httpConnectionTimeoutMS, int httpRequestTimeoutMS, int httpPort, int httpsPort) { // 设置一些基本参数 HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1); HttpProtocolParams.setContentCharset(httpParams, DEFAULT_CHARSET); HttpProtocolParams.setUseExpectContinue(httpParams, true); // HttpProtocolParams // .setUserAgent( // params, // "Mozilla/5.0(Linux;U;Android 2.2.1;en-us;Nexus One Build.FRG83) " // + // "AppleWebKit/553.1(KHTML,like Gecko) Version/4.0 Mobile Safari/533.1"); HttpProtocolParams.setUserAgent(httpParams, "Android " + Build.VERSION.RELEASE + ";" + "API " + Build.VERSION.SDK_INT + ";salama;"); // 超时设置 setTimeout(DEFAULT_CONNECTION_POOL_TIMEOUT_MS, DEFAULT_CONNECTION_TIMEOUT_MS, DEFAULT_REQUEST_TIMEOUT_MS); // 设置我们的HttpClient支持HTTP和HTTPS两种模式 SchemeRegistry schReg = new SchemeRegistry(); schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), httpPort)); schReg.register(new Scheme("https", new EasySSLSocketFactory(), httpsPort)); connectionManager = new ThreadSafeClientConnManager(httpParams, schReg); } public static void setUserAgent(String userAgent) { HttpProtocolParams.setUserAgent(httpParams, userAgent); } public static void setTimeout(int connectionPooltimeoutMS, int httpConnectionTimeoutMS, int httpRequestTimeoutMS) { ConnManagerParams.setTimeout(httpParams, connectionPooltimeoutMS); /* 连接超时 */ HttpConnectionParams.setConnectionTimeout(httpParams, httpConnectionTimeoutMS); /* 请求超时 */ HttpConnectionParams.setSoTimeout(httpParams, httpRequestTimeoutMS); } public static void setRequestTimeout(int httpRequestTimeoutMS) { HttpConnectionParams.setSoTimeout(httpParams, httpRequestTimeoutMS); } public static Object doBasicGet(boolean isDownload, String url, List<String> paramNames, List<String> paramValues, List<BasicNameValuePair> overrideHeaders) throws ClientProtocolException, IOException { return doBasicGet(isDownload, url, paramNames, paramValues, overrideHeaders, null); } public static boolean doBasicGetDownloadToSave(String url, List<String> paramNames, List<String> paramValues, String saveTo) throws ClientProtocolException, IOException { return (doBasicGet(true, url, paramNames, paramValues, null, saveTo) != null); } public static boolean doBasicGetDownloadToSave(String url, List<String> paramNames, List<String> paramValues, List<BasicNameValuePair> overrideHeaders, String saveTo) throws ClientProtocolException, IOException { return (doBasicGet(true, url, paramNames, paramValues, overrideHeaders, saveTo) != null); } private static Object doBasicGet(boolean isDownload, String url, List<String> paramNames, List<String> paramValues, List<BasicNameValuePair> overrideHeaders, String saveTo) throws ClientProtocolException, IOException { List<BasicNameValuePair> pairs = new ArrayList<BasicNameValuePair>(); //封装请求参数 if(paramNames != null) { for (int i = 0; i < paramNames.size(); i++) { pairs.add(new BasicNameValuePair(paramNames.get(i), paramValues .get(i))); } } //URL Params StringBuilder urlWithParams = new StringBuilder(url); if(url.indexOf("?") < 0) { urlWithParams.append("?"); } urlWithParams.append(URLEncodedUtils.format(pairs, DEFAULT_CHARSET)); //Http client HttpGet request = new HttpGet(urlWithParams.toString()); try { addDefaultHeaders(request, overrideHeaders); HttpResponse response = getHttpClient().execute(request); if (response.getStatusLine().getStatusCode() == RESPONSE_STATUS_SUCCESS) { if(isDownload && saveTo != null && saveTo.length() > 0) { FileOutputStream fos = null; try { fos = new FileOutputStream(saveTo); int downloadLen = saveResponseContent(response.getEntity(), fos); if(downloadLen > 0) { return Boolean.valueOf(true); } else { return null; } } finally { try { fos.close(); } catch(Exception e) { } } } else { byte[] bResult = getResponseContent(response.getEntity()); if (bResult != null) { if (isDownload) { return bResult; } else { return new String(bResult, DEFAULT_CHARSET); } } else { return null; } } } else { if(response.getStatusLine().getStatusCode() == HTTP_STATUS_CODE_APP_TOKEN_INVALID) { SalamaAppService.singleton().appLogin(); } return null; } } finally { try { request.abort(); } catch(Exception e) { } } } public static Object doBasicPost(boolean isDownload, String url, List<String> paramNames, List<String> paramValues, List<BasicNameValuePair> overrideHeaders) throws ClientProtocolException, IOException { return doBasicPost(isDownload, url, paramNames, paramValues, overrideHeaders, null); } public static boolean doBasicPostDownloadToSave(String url, List<String> paramNames, List<String> paramValues, List<BasicNameValuePair> overrideHeaders, String saveTo) throws ClientProtocolException, IOException { return (doBasicPost(true, url, paramNames, paramValues, overrideHeaders, saveTo) != null); } public static Object doBasicPost(boolean isDownload, String url, List<String> paramNames, List<String> paramValues, List<BasicNameValuePair> overrideHeaders, String saveTo) throws ClientProtocolException, IOException { // 封装请求参数 List<BasicNameValuePair> pairs = new ArrayList<BasicNameValuePair>(); if(paramNames != null) { for (int i = 0; i < paramNames.size(); i++) { pairs.add(new BasicNameValuePair(paramNames.get(i), paramValues .get(i))); } } // 把请求参数变成请求体部分 UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(pairs, DEFAULT_CHARSET); HttpPost request = new HttpPost(url); try { addDefaultHeaders(request, overrideHeaders); request.setEntity(formEntity); HttpResponse response = getHttpClient().execute(request); if (response.getStatusLine().getStatusCode() == RESPONSE_STATUS_SUCCESS) { if(isDownload && saveTo != null && saveTo.length() > 0) { FileOutputStream fos = null; try { fos = new FileOutputStream(saveTo); int downloadLen = saveResponseContent(response.getEntity(), fos); if(downloadLen > 0) { return Boolean.valueOf(true); } else { return null; } } finally { try { fos.close(); } catch(Exception e) { } } } else { byte[] bResult = getResponseContent(response.getEntity()); if (bResult != null) { if (isDownload) { return bResult; } else { return new String(bResult, DEFAULT_CHARSET); } } else { return null; } } } else { if(response.getStatusLine().getStatusCode() == HTTP_STATUS_CODE_APP_TOKEN_INVALID) { SalamaAppService.singleton().appLogin(); } return null; } } finally { try { request.abort(); } catch(Exception e) { } } } public static Object doMultipartPost(boolean isDownload, String url, List<String> paramNames, List<String> paramValues, List<MultiPartFile> filePartValues) throws ClientProtocolException, IOException { return doMultipartPost(isDownload, url, paramNames, paramValues, filePartValues, null); } public static boolean doMultipartPostDownloadToSave(String url, List<String> paramNames, List<String> paramValues, List<MultiPartFile> filePartValues, String saveTo) throws ClientProtocolException, IOException { return (doMultipartPost(true, url, paramNames, paramValues, filePartValues, saveTo) != null); } private static Object doMultipartPost(boolean isDownload, String url, List<String> paramNames, List<String> paramValues, List<MultiPartFile> filePartValues, String saveTo) throws ClientProtocolException, IOException { MultipartEntity multipartEntity = new MultipartEntity( HttpMultipartMode.BROWSER_COMPATIBLE, null, DefaultCharset); // 封装请求参数 if(paramNames != null) { for (int i = 0; i < paramNames.size(); i++) { multipartEntity.addPart(paramNames.get(i), new StringBody(paramValues.get(i), DefaultCharset)); } } // 上传文件 if(filePartValues != null) { for (int i = 0; i < filePartValues.size(); i++) { multipartEntity.addPart(filePartValues.get(i).getName(), new FileBody( filePartValues.get(i).getFile())); } } // 使用HttpPost对象设置发送的URL路径 HttpPost request = new HttpPost(url); try { addPostMultipartHeaders(request); request.setEntity(multipartEntity); HttpResponse response = getHttpClient().execute(request); if (response.getStatusLine().getStatusCode() == RESPONSE_STATUS_SUCCESS) { if(isDownload && saveTo != null && saveTo.length() > 0) { FileOutputStream fos = null; try { fos = new FileOutputStream(saveTo); int downloadLen = saveResponseContent(response.getEntity(), fos); if(downloadLen > 0) { return Boolean.valueOf(true); } else { return null; } } finally { try { fos.close(); } catch(Exception e) { } } } else { byte[] bResult = getResponseContent(response.getEntity()); if (bResult != null) { if (isDownload) { return bResult; } else { return new String(bResult, DEFAULT_CHARSET); } } else { return null; } } } else { if(response.getStatusLine().getStatusCode() == HTTP_STATUS_CODE_APP_TOKEN_INVALID) { SalamaAppService.singleton().appLogin(); } return null; } } finally { try { request.abort(); } catch(Exception e) { } } } private static HttpClient getHttpClient() { HttpClient customerHttpClient = new DefaultHttpClient(connectionManager, httpParams); return customerHttpClient; } private static void addDefaultHeaders(HttpRequestBase request) { request.addHeader("Content-Type", "application/x-www-form-urlencoded"); request.addHeader("Accept-Encoding", "gzip"); request.addHeader("accept", "*/*"); } private static void addDefaultHeaders(HttpRequestBase request, List<BasicNameValuePair> overrideHeaders) { if(overrideHeaders == null) { addDefaultHeaders(request); } else { BasicNameValuePair nameVal = null; for(int i = 0; i < overrideHeaders.size(); i++) { nameVal = overrideHeaders.get(i); request.addHeader(nameVal.getName(), nameVal.getValue()); } } } private static void addPostMultipartHeaders(HttpRequestBase request) { //request.addHeader("Content-Type", "multipart/form-data"); request.addHeader("Accept-Encoding", "gzip"); request.addHeader("accept", "*/*"); } private static byte[] getResponseContent(HttpEntity httpEntity) throws IOException { ByteArrayOutputStream output = new ByteArrayOutputStream(); saveResponseContent(httpEntity, output); return output.toByteArray(); } private static int saveResponseContent(HttpEntity httpEntity, OutputStream output) throws IOException { InputStream is = null; BufferedInputStream bis = null; try { is = httpEntity.getContent(); bis = new BufferedInputStream(is); boolean isGzip = false; HeaderElement[] headers = httpEntity.getContentEncoding().getElements(); if(headers != null) { for(int i = 0; i < headers.length; i++) { SSLog.d("HttpClientUtil", "HttpHeader " + headers[i].getName() + ":" + headers[i].getValue()); if("gzip".equalsIgnoreCase(headers[i].getName())) { isGzip = true; } } } /* byte[] gzipSignBytes = new byte[2]; bis.mark(2); int readed = bis.read(gzipSignBytes, 0, 2); if(readed == 0) { return 0; } else */ { //bis.reset(); InputStream is2 = null; try { //if((readed == 2) && (gzipSignBytes[0] == 31) && (gzipSignBytes[1] == 139)) { if(isGzip) { //gzip is2 = new GZIPInputStream(bis); } else { is2 = bis; } return readAllBytesToOutput(is2, output); } finally { try { is2.close(); } catch(Exception e) { } } } } finally { try { bis.close(); } catch(Exception e) { } try { is.close(); } catch(Exception e) { } try { httpEntity.consumeContent(); } catch(Exception e) { } } } /* private static byte[] readAllBytes(InputStream is) throws IOException { ByteArrayOutputStream output = new ByteArrayOutputStream(); byte[] tempBuffer = new byte[TEMP_BUFFER_DEFAULT_LENGTH]; int readed; while(true) { readed = is.read(tempBuffer, 0, TEMP_BUFFER_DEFAULT_LENGTH); if(readed < 0) { //no more to read break; } if(readed != 0) { output.write(tempBuffer, 0, readed); } } return output.toByteArray(); } */ private static int readAllBytesToOutput(InputStream is, OutputStream output) throws IOException { //ByteArrayOutputStream output = new ByteArrayOutputStream(); byte[] tempBuffer = new byte[TEMP_BUFFER_DEFAULT_LENGTH]; int readed; int totalRead = 0; while(true) { readed = is.read(tempBuffer, 0, TEMP_BUFFER_DEFAULT_LENGTH); if(readed < 0) { //no more to read break; } totalRead += readed; if(readed != 0) { output.write(tempBuffer, 0, readed); output.flush(); } } return totalRead; } }