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 获取。