MiniHttpClient

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ù)和文件上傳。
  • 方便擴展,自定義功能。

四:引入(最新版本)

  1. Maven
<dependency>
  <groupId>com.itgowo</groupId>
  <artifactId>MiniHttpClient</artifactId>
  <version>0.0.43</version>
  <type>pom</type>
</dependency>
  1. 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)用只是繼承封裝一層,此庫比較簡單,按需繼承改造。

七:原理解析

  1. 以HttpURLConnection為基礎(chǔ)開發(fā),需要學會簡單使用HttpURLConnection才能更好理解這個庫。
  2. 最核心請求類是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();
    }
  1. 通過prepare()可以設(shè)置header和上傳文件和下載目錄等。返回值是String類型,就是請求的Body部分,通常的接口請求json文本就是放到這里,請求json文本就不要設(shè)置上傳文件了。如果是文件上傳,需要這樣定義:
           protected String prepare(RequestClient requestClient)) {
                if (headers1 != null) {
                    requestClient.addHeaders(headers1);
                }
                requestClient.setUploadFiles(uploadFiles1);
                return null;
            }
  1. 如果是文件下載,請求的body需不需要看你們接口定義,一般靜態(tài)資源請求是GET方法,body為null,可以這樣定義:
            protected String prepare(RequestClient requestClient)) {
                if (headers1 != null) {
                    requestClient.addHeaders(headers1);
                }
                return null;
            }
  1. 如果用同步方法,只需要RequestClient用HttpResponse接收即可,如下:
        RequestClient requestClient = new RequestClient(url, method.getMethod(), timeout, new onSimpleCallbackListener()) {};
        return requestClient.request();
  1. 說說異步類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);
        }
    }
}
  1. 具體請求內(nèi)容請看代碼,其中有各種判斷解析,文件下載只認application/octet-stream,這點算是不足。文件下載還需要注意,執(zhí)行success()回調(diào)不代表文件下載完了,在返回的DownloadFile對象中封裝了輸入流,需要執(zhí)行saveToFile(下載目錄)才能真正保存到文件,saveToFile()方法也會觸發(fā)onProcess()進度回調(diào)。

八:小期待

以下項目都是我圍繞遠程控制寫的項目和子項目。都給star一遍吧。??

項目(Github) 語言 其他地址 運行環(huán)境 項目說明
RemoteDataControllerForWeb JavaScript 簡書 瀏覽器 遠程數(shù)據(jù)調(diào)試控制臺Web端
RemoteDataControllerForAndroid Java 簡書 Android設(shè)備 遠程數(shù)據(jù)調(diào)試Android端
RemoteDataControllerForServer Java 簡書 運行Java的設(shè)備 遠程數(shù)據(jù)調(diào)試Server端
MiniHttpClient Java 簡書 運行Java的設(shè)備 精簡的HttpClient
MiniHttpServer Java 簡書 運行Java的設(shè)備 支持部分Http協(xié)議的Server
MiniTCPClient Java 簡書 運行Java的設(shè)備 TCP長連接庫,支持粘包拆包處理
PackageMessage Java 簡書 運行Java的設(shè)備 TCP粘包與半包解決方案
ByteBuffer Java 簡書 運行Java的設(shè)備 二進制處理工具類
DataTables.AltEditor JavaScript 簡書 瀏覽器 Web端表格編輯組件

我的小站:IT狗窩
技術(shù)聯(lián)系QQ:1264957104

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 今天,看了兩部電影《戰(zhàn)狼2》和紀錄片《二十二》。兩部片子差一個小時,帶著觀《戰(zhàn)狼2》后的未了激情,一部平靜...
    方舟74閱讀 192評論 2 2
  • 根本不是一個世界的,何必強求。
    蝸牛小姐胡擦黑閱讀 109評論 0 0
  • 早讀是我們初中高中必須要面臨的逃避不了的事情也是最苦惱的事情,每天早晨天還沒亮就被宿管大叔的口哨聲吵醒,從睡夢中驚...
    小米安閱讀 195評論 0 0
  • 非典型零零后。 寫這篇莫名其妙的東西的目的是想要記錄一下我們蛋蛋后的真實生活(勿上升真人),畢竟是21世紀的新一代...
    非典型零零后閱讀 465評論 0 2
  • 一心想著放飛自我的某位同學,我來給你分享一下放飛自我的理解:讓所有的煩惱隨風而去,把所有的美好留在心中,還有,記得...
    何時再出發(fā)閱讀 393評論 1 1