A simple http client framework based on HttpURLConnection wrapper
MiniHttpClient
一:開發(fā)環(huán)境
Mac OS 10、Java 1.8、IDEA(Gradle工程)
二:介紹
基于Java HttpURLConnection實現(xiàn)Http客戶端,支持普通接口請求和表單上傳文件及文件下載等。使用線程池實現(xiàn)同步Future和異步請求。
目前判斷以下ContentType為文本接收,其余認為文件下載:
ContentType |
類型 |
說明 |
空 |
空 |
沒有指明數(shù)據(jù)類型,默認按文本處理 |
application/json |
Json文本 |
常見接口請求 |
text/html |
htm或者html等 |
網(wǎng)頁文件 |
text/plain |
純文本 |
txt等文件,以文本返回,不按文件下載 |
text/xml |
xml類文件 |
xml及其衍生文件格式大多數(shù)用這種類型 |
三:特點
- 純Java API實現(xiàn),輕巧。
- 支持同步和異步兩種方式。
- 獨立線程發(fā)起請求,支持線程池管理。
- 支持POST表單數(shù)據(jù)和文件上傳。
- 方便擴展,自定義功能。
- Maven
<dependency>
<groupId>com.itgowo</groupId>
<artifactId>MiniHttpClient</artifactId>
<version>0.0.43</version>
<type>pom</type>
</dependency>
- Gradle
implementation 'com.itgowo:MiniHttpClient:0.0.43'
五:簡單使用(庫Jar中有Demo類,可以參考)
Demo.java
1.模擬表單上傳,POST方式
public static void testUploadFile() {
String url = "http://127.0.0.1:12111";
List<File> files = new ArrayList<>();
File file = new File("/Users/lujianchao/Desktop/RDC1.png");
files.add(file);
HttpClient.RequestUploadFiles(url, null, files, new onSimpleCallbackListener() {
@Override
public void onError(HttpResponse httpResponse, Exception e) {
System.out.println("httpResponse = [" + httpResponse + "], e = [" + e + "]");
}
@Override
public void onProcess(File file, int countBytes, int processBytes) throws Exception {
System.out.println("file = [" + file + "], countBytes = [" + countBytes + "], processBytes = [" + processBytes + "]");
}
@Override
public void onSuccess(HttpResponse httpResponse) throws Exception {
System.out.println("httpResponse = [" + httpResponse + "]");
}
});
}
2.同步上傳文件
public static void testSyncUploadFile() throws Exception {
String url = "http://127.0.0.1:12111/app.js";
List<File> files = new ArrayList<>();
File file = new File("/Users/lujianchao/Desktop/RDC1.png");
files.add(file);
HttpResponse httpResponse = HttpClient.RequestSync(url, HttpMethod.POST, null, files, null);
if (httpResponse.isSuccess()) {
System.out.println("上傳成功");
}
}
3.提交數(shù)據(jù)
public static void testRequest() {
String url = "http://127.0.0.1:12111/app.js";
Map<String, String> headers = new HashMap<>();
headers.put("content-type", "application/json");
String httpBody = "{\"name\":\"張三\"}";
HttpClient.Request(url, HttpMethod.POST, headers, httpBody, new onSimpleCallbackListener() {
@Override
public void onError(HttpResponse response, Exception e) {
e.printStackTrace();
System.out.println("response = [" + response + "], e = [" + e + "]");
}
@Override
public void onSuccess(HttpResponse response) throws Exception {
System.out.println("response = [" + response + "]");
}
});
}
4.同步請求
public static void testRequestSync() {
String url = "http://127.0.0.1:12111/app.js";
Map<String, String> headers = new HashMap<>();
headers.put("content-type", "application/json");
String httpBody = "{\"name\":\"張三\"}";
try {
HttpResponse response = HttpClient.RequestSync(url, HttpMethod.POST, headers, null, httpBody);
System.out.println(response);
} catch (Exception e) {
e.printStackTrace();
}
}
5.文件下載,如果文件已存在,則用時間戳拼在文件名前面,通過DownloadFile的getOriginFileName()方法獲取瀏覽器返回文件名,如果是重定向獲取的文件下載十分有意義,不能用原始url判斷文件名。
public static void testDownloadFile() {
String downloadUrl = "http://file.itgowo.com/itgowo/RemoteDataController/web_app.zip";
String downloadDir = "temp";
HttpClient.RequestGetFile(downloadUrl, null, new onSimpleCallbackListener() {
@Override
public void onError(HttpResponse response, Exception e) {
e.printStackTrace();
System.out.println("response = [" + response + "], e = [" + e + "]");
}
@Override
public void onSuccess(HttpResponse response) throws Exception {
//下載文件不會觸發(fā)
System.out.println("response = [" + response + "]");
}
@Override
public void onSuccess(HttpResponse httpResponse, DownloadFile file) throws Exception {
file.saveToFile(downloadDir);
System.out.println("httpResponse = [" + httpResponse + "], file = [" + file.getFile() + "]");
}
@Override
public void onProcess(File file, int countBytes, int processBytes) throws Exception {
System.out.println("file = [" + file + "], countBytes = [" + countBytes + "], processBytes = [" + processBytes + "]");
}
});
}
6.同步方式下載文件,文件對象放在HttpResponse中的downloadFile里
public static void testSyncDownloadFile() {
try {
String url = "http://127.0.0.1:12111/app.js";
HttpResponse response = HttpClient.RequestSync(url, HttpMethod.GET, null, null);
System.out.println(response.getDownloadFile());
} catch (Exception e) {
e.printStackTrace();
}
}
六:說明
1. 回調(diào)接口onCallbackListener
- public void onError(HttpResponse response, Exception e)
發(fā)生錯誤時回調(diào) |
|
HttpResponse |
請求結(jié)果,當http狀態(tài)碼不是200系列時,body可能包含錯誤信息 |
Exception |
異常類 |
- public void onSuccess(HttpResponse response) throws Exception
非文件下載請求成功回調(diào) |
|
HttpRespons |
請求結(jié)果,當http狀態(tài)碼是200系列時返回 |
- public void onSuccess(HttpResponse httpResponse, DownloadFile file) throws Exception
文件下載請求成功回調(diào) |
|
HttpResponse |
請求結(jié)果,downloadFile為下載文件類,同第二個參數(shù) |
DownloadFile |
下載文件類,此時只讀取了header信息,需要方法saveToFile(downloadDir)去保存文件 |
- public void onProcess(File file, int countBytes, int processBytes) throws Exception
下載文件時:saveToFile(downloadDir)方法執(zhí)行后,觸發(fā)下載進度;上傳文件時:觸發(fā)上傳進度 |
|
File |
下載文件或上傳文件 |
countBytes |
文件大小 |
processBytes |
文件大小 |
2. 請求方式
分為同步請求和異步請求,功能全部封裝到同步模塊,異步調(diào)用只是繼承封裝一層,此庫比較簡單,按需繼承改造。
七:原理解析
- 以HttpURLConnection為基礎(chǔ)開發(fā),需要學會簡單使用HttpURLConnection才能更好理解這個庫。
- 最核心請求類是RequestClient,封裝了request()方法開始請求,request()執(zhí)行先觸發(fā)prepare(RequestClient requestClient)方法,初始化請求參數(shù)。例如:
public static HttpResponse RequestSync(String url, HttpMethod method, Map<String, String> headers1, List<File> uploadFiles1, String requestJson) throws Exception {
RequestClient requestClient = new RequestClient(url, method.getMethod(), timeout, new onSimpleCallbackListener()) {
@Override
protected String prepare(RequestClient requestClient) {
if (headers1 != null) {
requestClient.addHeaders(headers1);
}
requestClient.setUploadFiles(uploadFiles1);
return requestJson;
}
};
return requestClient.request();
}
- 通過prepare()可以設(shè)置header和上傳文件和下載目錄等。返回值是String類型,就是請求的Body部分,通常的接口請求json文本就是放到這里,請求json文本就不要設(shè)置上傳文件了。如果是文件上傳,需要這樣定義:
protected String prepare(RequestClient requestClient)) {
if (headers1 != null) {
requestClient.addHeaders(headers1);
}
requestClient.setUploadFiles(uploadFiles1);
return null;
}
- 如果是文件下載,請求的body需不需要看你們接口定義,一般靜態(tài)資源請求是GET方法,body為null,可以這樣定義:
protected String prepare(RequestClient requestClient)) {
if (headers1 != null) {
requestClient.addHeaders(headers1);
}
return null;
}
- 如果用同步方法,只需要RequestClient用HttpResponse接收即可,如下:
RequestClient requestClient = new RequestClient(url, method.getMethod(), timeout, new onSimpleCallbackListener()) {};
return requestClient.request();
- 說說異步類RequestAsyncClient,其實只是實現(xiàn)了runnable接口,在run()方法中觸發(fā)request(),然后判斷執(zhí)行回調(diào),代碼如下:
public abstract class RequestAsyncClient extends RequestClient implements Runnable {
public RequestAsyncClient(String url, String method, int timeout, onCallbackListener listener) {
super(url, method, timeout, listener);
}
@Override
public void run() {
try {
request();
if (httpResponse.isSuccess()) {
if (httpResponse.isDownloadFile()) {
listener.onSuccess(httpResponse, httpResponse.getDownloadFile());
} else {
listener.onSuccess(httpResponse);
}
} else {
listener.onError(httpResponse, new Exception("code:" + httpResponse.getResponseCode() + " msg:" + httpResponse.getResponseMessage()));
}
} catch (Exception e) {
listener.onError(httpResponse.setSuccess(false), e);
}
}
}
- 具體請求內(nèi)容請看代碼,其中有各種判斷解析,文件下載只認application/octet-stream,這點算是不足。文件下載還需要注意,執(zhí)行success()回調(diào)不代表文件下載完了,在返回的DownloadFile對象中封裝了輸入流,需要執(zhí)行saveToFile(下載目錄)才能真正保存到文件,saveToFile()方法也會觸發(fā)onProcess()進度回調(diào)。
八:小期待
以下項目都是我圍繞遠程控制寫的項目和子項目。都給star一遍吧。??
我的小站:IT狗窩
技術(shù)聯(lián)系QQ:1264957104