package com.mime.qweibo; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.methods.ByteArrayRequestEntity; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.multipart.FilePart; import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity; import org.apache.commons.httpclient.methods.multipart.Part; import org.apache.commons.httpclient.methods.multipart.StringPart; import com.mime.qweibo.utils.QHttpUtil; /** * Note: This is not really an async http client. You may try * Ning(https://github.com/AsyncHttpClient/async-http-client), Apache Geronimo * async-http-client, or anything else if you really need. * */ public class QAsyncHttpClient { private static final int CONNECTION_TIMEOUT = 20000; /** * Using asynchronously GET method. * * @param url * The remote URL. * @param queryString * The query string containing parameters * @param callback * Callback handler. * @param cookie * Cookie response to handler. * @return Whether request has started. */ public boolean httpGet(String url, String queryString, QAsyncHandler callback, Object cookie) { if (url == null || url.equals("")) { return false; } if (queryString != null && !queryString.equals("")) { url += "?" + queryString; } GetMethod httpGet = new GetMethod(url); httpGet.getParams().setParameter("http.socket.timeout", new Integer(CONNECTION_TIMEOUT)); mThreadPool.submit(new AsyncThread(httpGet, callback, cookie)); return true; } /** * Using asynchronously POST method. * * @param url * The remote URL. * @param queryString * The query string containing parameters * @param callback * Callback handler. * @param cookie * Cookie response to handler. * @return Whether request has started. */ public boolean httpPost(String url, String queryString, QAsyncHandler callback, Object cookie) { if (url == null || url.equals("")) { return false; } PostMethod httpPost = new PostMethod(url); httpPost.addParameter("Content-Type", "application/x-www-form-urlencoded"); httpPost.getParams().setParameter("http.socket.timeout", new Integer(CONNECTION_TIMEOUT)); if (queryString != null && !queryString.equals("")) { httpPost.setRequestEntity(new ByteArrayRequestEntity(queryString .getBytes())); } mThreadPool.submit(new AsyncThread(httpPost, callback, cookie)); return true; } /** * Using asynchronously POST method with multiParts. * * @param url * The remote URL. * @param queryString * The query string containing parameters * @param callback * Callback handler. * @param cookie * Cookie response to handler. * @return Whether request has started. */ public boolean httpPostWithFile(String url, String queryString, List<QParameter> files, QAsyncHandler callback, Object cookie) { if (url == null || url.equals("")) { return false; } url += '?' + queryString; PostMethod httpPost = new PostMethod(url); List<QParameter> listParams = QHttpUtil.getQueryParameters(queryString); int length = listParams.size() + (files == null ? 0 : files.size()); Part[] parts = new Part[length]; int i = 0; for (QParameter param : listParams) { parts[i++] = new StringPart(param.mName, QHttpUtil.formParamDecode(param.mValue), "UTF-8"); } try { for (QParameter param : files) { File file = new File(param.mValue); parts[i++] = new FilePart(param.mName, file.getName(), file, QHttpUtil.getContentType(file), "UTF-8"); } } catch (FileNotFoundException e) { e.printStackTrace(); return false; } httpPost.setRequestEntity(new MultipartRequestEntity(parts, httpPost .getParams())); mThreadPool.submit(new AsyncThread(httpPost, callback, cookie)); return true; } private ExecutorService mThreadPool = Executors.newFixedThreadPool(20); /** * Thread for asynchronous HTTP request. * */ class AsyncThread extends Thread { private HttpMethod mHttpMedthod; private QAsyncHandler mAsyncHandler; private Object mCookie; public AsyncThread(HttpMethod method, QAsyncHandler handler, Object cookie) { this.mHttpMedthod = method; this.mAsyncHandler = handler; this.mCookie = cookie; } @Override public void run() { String responseData = null; HttpClient httpClient = new HttpClient(); int statusCode = -1; try { statusCode = httpClient.executeMethod(mHttpMedthod); if (statusCode != HttpStatus.SC_OK) { System.err.println("HttpMethod failed: " + mHttpMedthod.getStatusLine()); } responseData = mHttpMedthod.getResponseBodyAsString(); } catch (HttpException e) { e.printStackTrace(); if (mAsyncHandler != null) { mAsyncHandler.onThrowable(e, mCookie); } return; } catch (IOException e) { e.printStackTrace(); if (mAsyncHandler != null) { mAsyncHandler.onThrowable(e, mCookie); } return; } finally { mHttpMedthod.releaseConnection(); httpClient = null; } if (mAsyncHandler != null) { mAsyncHandler.onCompleted(statusCode, responseData, mCookie); } } } }