2. 概述

Unirest 是由 Mashape 开发的轻量级 HTTP 客户端库。除了 Java,它还支持 Node.js、.Net、Python、Ruby 等多种语言。

⚠️ 本文所有示例将使用 mocky.io 提供的模拟接口。

3. Maven 设置

首先添加必要的依赖:

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

最新版本可在 Maven Central 查询。

4. 简单请求

通过一个基础请求理解框架语义:

@Test
public void shouldReturnStatusOkay() {
    HttpResponse<JsonNode> jsonResponse 
      = Unirest.get("http://www.mocky.io/v2/5a9ce37b3100004f00ab5154")
      .header("accept", "application/json").queryString("apiKey", "123")
      .asJson();

    assertNotNull(jsonResponse.getBody());
    assertEquals(200, jsonResponse.getStatus());
}

✅ API 设计流畅高效,可读性强:

  • 通过 header()fields() 添加请求头和参数
  • 调用 asJson() 触发请求(其他选项:asBinary(), asString(), asObject()

批量添加请求头/参数时,可使用 Map:

@Test
public void shouldReturnStatusAccepted() {
    Map<String, String> headers = new HashMap<>();
    headers.put("accept", "application/json");
    headers.put("Authorization", "Bearer 5a9ce37b3100004f00ab5154");

    Map<String, Object> fields = new HashMap<>();
    fields.put("name", "Sam Baeldung");
    fields.put("id", "PSP123");

    HttpResponse<JsonNode> jsonResponse 
      = Unirest.put("http://www.mocky.io/v2/5a9ce7853100002a00ab515e")
      .headers(headers).fields(fields)
      .asJson();
 
    assertNotNull(jsonResponse.getBody());
    assertEquals(202, jsonResponse.getStatus());
}

4.1. 传递查询参数

使用 queryString() 添加 URL 查询参数:

HttpResponse<JsonNode> jsonResponse 
  = Unirest.get("http://www.mocky.io/v2/5a9ce37b3100004f00ab5154")
  .queryString("apiKey", "123")

4.2. 使用路径参数

通过 routeParam() 处理 URL 路径参数:

HttpResponse<JsonNode> jsonResponse 
  = Unirest.get("http://www.mocky.io/v2/5a9ce37b3100004f00ab5154/{userId}")
  .routeParam("userId", "123")

❌ 参数占位符名称必须与方法第一个参数一致。

4.3. 带请求体的请求

使用 body() 传递字符串/JSON 请求体:

@Test
public void givenRequestBodyWhenCreatedThenCorrect() {

    HttpResponse<JsonNode> jsonResponse 
      = Unirest.post("http://www.mocky.io/v2/5a9ce7663100006800ab515d")
      .body("{\"name\":\"Sam Baeldung\", \"city\":\"viena\"}")
      .asJson();
 
    assertEquals(201, jsonResponse.getStatus());
}

4.4. 对象映射器

使用 asObject() 或对象 body() 前需配置对象映射器。这里以 Jackson 为例:

添加依赖:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.17.2</version>
</dependency>

配置映射器(只需初始化一次):

Unirest.setObjectMapper(new ObjectMapper() {
    com.fasterxml.jackson.databind.ObjectMapper mapper 
      = new com.fasterxml.jackson.databind.ObjectMapper();

    public String writeValue(Object value) {
        return mapper.writeValueAsString(value);
    }

    public <T> T readValue(String value, Class<T> valueType) {
        return mapper.readValue(value, valueType);
    }
});

使用自定义对象测试:

@Test
public void givenArticleWhenCreatedThenCorrect() {
    Article article 
      = new Article("ID1213", "Guide to Rest", "baeldung");
    HttpResponse<JsonNode> jsonResponse 
      = Unirest.post("http://www.mocky.io/v2/5a9ce7663100006800ab515d")
      .body(article)
      .asJson();
 
    assertEquals(201, jsonResponse.getStatus());
}

5. 请求方法

支持所有标准 HTTP 方法:

  • POST:Unirest.post("http://www.mocky.io/v2/5a9ce7663100006800ab515d")
  • PUT:Unirest.put("http://www.mocky.io/v2/5a9ce7663100006800ab515d")
  • GET:Unirest.get("http://www.mocky.io/v2/5a9ce7663100006800ab515d")
  • DELETE:Unirest.delete("http://www.mocky.io/v2/5a9ce7663100006800ab515d")
  • PATCH:Unirest.patch("http://www.mocky.io/v2/5a9ce7663100006800ab515d")
  • OPTIONS:Unirest.options("http://www.mocky.io/v2/5a9ce7663100006800ab515d")

6. 响应处理

获取响应信息:

// 状态码
jsonResponse.getStatus()

// 响应头
jsonResponse.getHeaders();

// 响应体
jsonResponse.getBody();          // 已解析(使用对象映射器)
jsonResponse.getRawBody();      // 原始字节流

7. 处理异步请求

支持 Future 和回调两种异步模式:

@Test
public void whenAysncRequestShouldReturnOk() {
    Future<HttpResponse<JsonNode>> future = Unirest.post(
      "http://www.mocky.io/v2/5a9ce37b3100004f00ab5154?mocky-delay=10000ms")
      .header("accept", "application/json")
      .asJsonAsync(new Callback<JsonNode>() {
        public void failed(UnirestException e) {
            // 请求失败处理
        }
        public void completed(HttpResponse<JsonNode> response) {
            // 请求成功处理
        }
        public void cancelled() {
            // 请求取消处理
        }
    });
 
    assertEquals(200, future.get().getStatus());
}

Callback<T> 接口需实现三个方法:

  • failed(): 处理异常
  • cancelled(): 处理取消
  • completed(): 处理成功响应

8. 文件上传

8.1. 文件对象上传

@Test
public void givenFileWhenUploadedThenCorrect() {
    HttpResponse<JsonNode> jsonResponse = Unirest.post(
      "http://www.mocky.io/v2/5a9ce7663100006800ab515d")
      .field("file", new File("/path/to/file"))
      .asJson();
 
    assertEquals(201, jsonResponse.getStatus());
}

8.2. 字节流上传

@Test
public void givenByteStreamWhenUploadedThenCorrect() {
    try (InputStream inputStream = new FileInputStream(
      new File("/path/to/file/artcile.txt"))) {
        byte[] bytes = new byte[inputStream.available()];
        inputStream.read(bytes);
        HttpResponse<JsonNode> jsonResponse = Unirest.post(
          "http://www.mocky.io/v2/5a9ce7663100006800ab515d")
          .field("file", bytes, "article.txt")
          .asJson();
 
        assertEquals(201, jsonResponse.getStatus());
    }
}

8.3. 输入流上传

@Test
public void givenInputStreamWhenUploadedThenCorrect() {
    try (InputStream inputStream = new FileInputStream(
      new File("/path/to/file/artcile.txt"))) {

        HttpResponse<JsonNode> jsonResponse = Unirest.post(
          "http://www.mocky.io/v2/5a9ce7663100006800ab515d")
          .field("file", inputStream, ContentType.APPLICATION_OCTET_STREAM, "article.txt").asJson();
 
        assertEquals(201, jsonResponse.getStatus());
    }
}

9. Unirest 配置

9.1. 连接池配置

Unirest.setConcurrency(20, 5); // 最大连接数/每路由最大连接数

9.2. 超时设置(毫秒)

Unirest.setTimeouts(20000, 15000); // 连接超时/套接字超时

9.3. 全局请求头

Unirest.setDefaultHeader("X-app-name", "baeldung-unirest");
Unirest.setDefaultHeader("X-request-id", "100004f00ab5");

// 清除全局头
Unirest.clearDefaultHeaders();

9.4. 代理配置

Unirest.setProxy(new HttpHost("localhost", 8080));

9.5. 资源清理

⚠️ 应用退出前必须关闭后台事件循环:

Unirest.shutdown();

10. 总结

本文介绍了轻量级 HTTP 客户端 Unirest 的核心功能:

  • ✅ 同步/异步请求处理
  • ✅ 文件上传与对象映射
  • ✅ 连接池、代理等高级配置

完整示例代码可在 GitHub 获取。


原始标题:A Guide to Unirest | Baeldung