Unirest一款輕量級的HTTP客戶端庫

在java工程裏如果需要透傳什麼信息給一個http接口的話,我們往往會使用HttpClient這個類,然後set很多param參數,這個類自然是很優秀的也被很多線上工程使用着,但是使用的過程中總不是那麼的簡便,比如需要引很多包,包與包之間還經常會有衝突,demo並不統一(每一個工程師寫出來的mock http的代碼有可能都是不一樣的)。講真,我在實踐過程中,如果沒有工具類從頭開始自己寫一個http的請求,還是要花很長時間的。

現在,有一個類庫幫我們解決了這個問題——Unirest。

 

Unirest的特性

1.能夠僞造GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS 這些請求。

2.支持同步/異步請求。

3.支持表單提交,文件上傳,自定義實體。

4.支持路徑參數

5.支持gzip

6.支持本地的 Basic Authentication

7.自定義超時,併發級別和代理設置。

8.爲每個請求自定義默認請求頭。

9.自定義HttpClientHttpAsyncClient

10.自動解析JSON

11.自定義的將返回的json數據轉換成Java對象。

 

Maven:

<dependency>
    <groupId>com.mashape.unirest</groupId>
    <artifactId>unirest-java</artifactId>
    <version>1.4.9</version>
</dependency>

需要依賴如下的maven:

<dependency>
  <groupId>org.apache.httpcomponents</groupId>
  <artifactId>httpclient</artifactId>
  <version>4.3.6</version>
</dependency>
<dependency>
  <groupId>org.apache.httpcomponents</groupId>
  <artifactId>httpasyncclient</artifactId>
  <version>4.0.2</version>
</dependency>
<dependency>
  <groupId>org.apache.httpcomponents</groupId>
  <artifactId>httpmime</artifactId>
  <version>4.3.6</version>
</dependency>
<dependency>
  <groupId>org.json</groupId>
  <artifactId>json</artifactId>
  <version>20140107</version>
</dependency>

 

創建請求

HttpResponse<JsonNode> jsonResponse = Unirest.post("http://httpbin.org/post")
  .header("accept", "application/json")
  .queryString("apiKey", "123")
  .field("parameter", "value")
  .field("foo", "bar")
  .asJson();

如上,當調用asJson()這個方法的時候,這個post請求就被髮送了。不只包含json這種類型,還可以是JSON,Binary,String,Object等類型。

queryString和field比較類似,我理解queryString是get請求中用於拼接問好後面的參數,field用於post請求,但是該類並沒有很嚴格的要求,get和post都可以使用。

 

序列化

如果要求返回的直接是一個Java對象,那麼我們需要將json格式的數據轉成Java對象,這中間需要一些序列化的工具,個人比較喜歡Gson。

所以,在調用asObject(Class).body(Object)方法 之前,有必要實現一個自定義的ObjectMapper接口。這應該只在第一次完成,因爲ObjectMapper的實例將在全局共享。

// Only one time
Unirest.setObjectMapper(new ObjectMapper() {
    private com.fasterxml.jackson.databind.ObjectMapper jacksonObjectMapper
                = new com.fasterxml.jackson.databind.ObjectMapper();
    
    public <T> T readValue(String value, Class<T> valueType) {
        try {
            return jacksonObjectMapper.readValue(value, valueType);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public String writeValue(Object value) {
        try {
            return jacksonObjectMapper.writeValueAsString(value);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }
});

// Response to Object
HttpResponse<Book> bookResponse = Unirest.get("http://httpbin.org/books/1").asObject(Book.class);
Book bookObject = bookResponse.getBody();

HttpResponse<Author> authorResponse = Unirest.get("http://httpbin.org/books/{id}/author")
    .routeParam("id", bookObject.getId())
    .asObject(Author.class);
    
Author authorObject = authorResponse.getBody();

// Object to Json
HttpResponse<JsonNode> postResponse = Unirest.post("http://httpbin.org/authors/post")
        .header("accept", "application/json")
        .header("Content-Type", "application/json")
        .body(authorObject)
        .asJson();

 

路徑參數

可以通過routeParam來設置路徑參數,比如:

Unirest.get("http://httpbin.org/{method}")
  .routeParam("method", "get")
  .queryString("name", "Mark")
  .asJson();

{method}這個佔位符就會變成get。

 

異步請求

有時候我們需要請求是異步的而不是阻塞的,Unirest支持回調方法,如下:

Future<HttpResponse<JsonNode>> future = Unirest.post("http://httpbin.org/post")
  .header("accept", "application/json")
  .field("param1", "value1")
  .field("param2", "value2")
  .asJsonAsync(new Callback<JsonNode>() {

    public void failed(UnirestException e) {
        System.out.println("The request has failed");
    }

    public void completed(HttpResponse<JsonNode> response) {
         int code = response.getStatus();
         Map<String, String> headers = response.getHeaders();
         JsonNode body = response.getBody();
         InputStream rawBody = response.getRawBody();
    }

    public void cancelled() {
        System.out.println("The request has been cancelled");
    }

});

 

文件上傳

只需將一個File或一個InputStream對象作爲字段傳遞即可,如下:

HttpResponse<JsonNode> jsonResponse = Unirest.post("http://httpbin.org/post")
  .header("accept", "application/json")
  .field("parameter", "value")
  .field("file", new File("/tmp/file"))
  .asJson();

自定義實體

HttpResponse<JsonNode> jsonResponse = Unirest.post("http://httpbin.org/post")
  .header("accept", "application/json")
  .body("{\"parameter\":\"value\", \"foo\":\"bar\"}")
  .asJson();

字節流作爲實體

final InputStream stream = new FileInputStream(new File(getClass().getResource("/image.jpg").toURI()));
final byte[] bytes = new byte[stream.available()];
stream.read(bytes);
stream.close();
final HttpResponse<JsonNode> jsonResponse = Unirest.post("http://httpbin.org/post")
  .field("name", "Mark")
  .field("file", bytes, "image.jpg")
  .asJson();

InputStream作爲實體

HttpResponse<JsonNode> jsonResponse = Unirest.post("http://httpbin.org/post")
  .field("name", "Mark")
  .field("file", new FileInputStream(new File(getClass().getResource("/image.jpg").toURI())), ContentType.APPLICATION_OCTET_STREAM, "image.jpg")
  .asJson();

基本認證

通過調用basicAuth(username, password)方法可以通過基本身份驗證來驗證請求:

HttpResponse<JsonNode> response = Unirest.get("http://httpbin.org/headers").basicAuth("username", "password").asJson();

請求

Unirest遵循構建器約定,可以通過一下幾種方式來構建一個http請求。

GetRequest request = Unirest.get(String url);
GetRequest request = Unirest.head(String url);
HttpRequestWithBody request = Unirest.post(String url);
HttpRequestWithBody request = Unirest.put(String url);
HttpRequestWithBody request = Unirest.patch(String url);
HttpRequestWithBody request = Unirest.options(String url);
HttpRequestWithBody request = Unirest.delete(String url);

 響應

收到響應後,Unirest以一個對象的形式返回結果,該對象有如下幾種 鍵:

  • .getStatus() – HTTP響應狀態代碼(例如:200)
  • .getStatusText() – HTTP響應狀態文本(示例:“確定”)
  • .getHeaders() – HTTP響應標頭
  • .getBody() – 適用的解析響應體,例如JSON響應被解析爲Objects / Associative Arrays。
  • .getRawBody() – 未解析的響應正文

高級配置

自定義HTTP客戶端

可以使用以下方法顯式設置自己的實現HttpClientHttpAsyncClient

Unirest.setHttpClient(httpClient);
Unirest.setAsyncHttpClient(asyncHttpClient);

超時

可以設置自定義連接和套接字超時值(以毫秒爲單位):

Unirest.setTimeouts(long connectionTimeout, long socketTimeout);

默認情況下,連接超時(連接到服務器所需的時間)是10000和套接字超時(接收數據所需的時間)是60000,也可以將這些超時中的任何一個設置爲零以禁用超時。

默認請求標頭

可以設置將在每個請求上發送的默認標頭:

Unirest.setDefaultHeader("Header1", "Value1");
Unirest.setDefaultHeader("Header2", "Value2");

也可以清楚這些頭信息:

Unirest.clearDefaultHeaders();

併發

如果需要調整同步或異步客戶端的性能,可以設置自定義併發級別:

Unirest.setConcurrency(int maxTotal, int maxPerRoute);

默認情況下,maxTotal(池中的總連接限制)200和maxPerRoute(每個目標主機的連接限制)是20

代理

您可以通過調用來設置代理:

Unirest.setProxy(new HttpHost("127.0.0.1", 8000));

退出申請

Unirest啓動後臺事件循環,在我們通過調用手動關閉所有線程之前,Java應用程序將無法退出:

Unirest.shutdown();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章