Java tutorial
/* * 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; } }