用谷歌的AsyncHttpClient簡單模仿安卓的AsyncHttpClient,實現非同步請求回撥函式返回值
阿新 • • 發佈:2019-02-18
實現思路
既然要呼叫Future.get() 才能激發訪問,那麼就想到了使用一個執行緒去訪問。我們就不需要等待阻塞了。
模仿安卓的AsyncHttpClient回撥。根據狀態回撥不同的函式。
實現的效果
執行程式碼...
非同步請求..不需要等待返回的結果,繼續執行下面的程式碼
執行程式碼...
AsyncHttpClient 主工具類
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import com.ning.http.client.AsyncHttpClient;
import com.ning.http.client.Response;
/**
* AsyncHttpClient請求工具箱
*
* @author Zq
*
*/
public class AsyncHttpKit {
private AsyncHttpKit() {
};
/** 預設編碼 **/
private static final String DEFAULT_CHARSET = "UTF-8";
/** 非同步請求物件 **/
private static AsyncHttpClient http = new AsyncHttpClient();
/** 快取執行緒池 **/
private static ExecutorService pool = Executors.newCachedThreadPool();
/**
*
* @param url 訪問連結,但是請注意,接收的url 必須符合URI協議,否則丟擲異常
* @param params 引數,其中不能有為null的引數值
* @param handler 非同步回撥輔助類
*/
public static void post(String url, Map<String, String> params,AsyncHttpResponseHandler handler){
handler.setFuture(post(url, params));
pool.execute(handler);
}
/**
* 非同步Post請求
*
* @param http
* @param url
* @param params
* 請求引數
* @return
*/
private static Future<Response> post(String url, Map<String, String> params) {
AsyncHttpClient.BoundRequestBuilder builder = http.preparePost(url);
builder.setBodyEncoding(DEFAULT_CHARSET);
if (params != null && !params.isEmpty()) {
Set<String> keys = params.keySet();
for (String key : keys) {
builder.addParameter(key, params.get(key));
}
}
Future<Response> f = null;
try {
f = builder.execute();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return f;
}
/**
* 非同步post請求
* @param url 請求地址
* @param s 引數為 json串 {xx:xx,...}
* @param handler
*/
public static void post(String url,String s,AsyncHttpResponseHandler handler){
handler.setFuture(post(url, s));
pool.execute(handler);
}
/**
* 非同步POST請求
*
* @param http
* @param url
* @param s
* json串
* @return
*/
private static Future<Response> post(String url, String s) {
AsyncHttpClient.BoundRequestBuilder builder = http.preparePost(url);
builder.setBodyEncoding(DEFAULT_CHARSET);
builder.setBody(s);
Future<Response> f = null;
try {
f = builder.execute();
} catch (IOException e) {
e.printStackTrace();
}
return f;
}
}
輔助類,模仿安卓的AsyncHttpResponseHandler
安卓的非同步請求
<dependency>
<groupId>com.loopj.android</groupId>
<artifactId>android-async-http</artifactId>
<version>1.4.5</version>
</dependency>
import java.util.concurrent.Future;
import com.ning.http.client.Response;
/**
* 非同步請求輔助類
* @author Zq
*
*/
public abstract class AsyncHttpResponseHandler implements Runnable {
private Future<Response> future = null;
@Override
public void run() {
int statusCode = 0;
try {
Response response = future.get(/*timout, TimeUnit.SECONDS*/);
statusCode = response.getStatusCode();
String responseBody = response.getResponseBody("UTF-8");
if (statusCode == 200) { //只有200狀態呼叫成功方法
this.onSuccess(statusCode, responseBody);
} else { //其他狀態呼叫失敗方法
this.onFailure(statusCode, responseBody,null);
}
} catch (InterruptedException e) { //請求過程中出現錯誤,請求狀態變成0,呼叫失敗的方法
this.onFailure(0, null, e);
} catch (ExecutionException e) {
this.onFailure(0, null, e);
} catch (IOException e) {
this.onFailure(statusCode, null, e);
}
/**
* 上面的處理過程,需要子類實現者手動的try掉onFailure和 onSuccess中的所有異常,否則會出現呼叫結果不準確的現象
*/
}
/**
* 請求成功:回撥函式
*
* @param status
* 狀態碼 200
* @param body
* 返回結果
*/
public abstract void onSuccess(int status, String body);
/**
* 請求失敗回撥函式
*
* @param status
* 除了200意外的所有狀態碼;如果返回0 請求的時候發生了異常,throwable屬性有值
* @param body
* 返回的結果
* @param throwable
* 丟擲錯誤異常
*/
public abstract void onFailure(int status, String body, Throwable throwable);
public Future<Response> getFuture() {
return future;
}
public void setFuture(Future<Response> future) {
this.future = future;
}
}