mcpField
U
unirest-java-3

unirest-java-3

github.com/full-stack-skills开发774 次安装5 周前更新
代码仓库

关于 unirest-java-3

面向 Java 8 及以上项目的 Unirest-Java 3.x 参考技能,介绍如何使用 Apache HttpClient 4 构建 HTTP 客户端。内容涵盖请求、响应、配置、模拟测试和缓存。

主要功能

  1. 01构建多种 HTTP 请求
  2. 02使用 GSON 映射 JSON 对象
  3. 03支持 CompletableFuture 异步请求
  4. 04配置代理、超时和连接池
  5. 05模拟测试与响应缓存

适用场景

  1. 01在 Java 项目中调用 REST API
  2. 02调试 HTTP 客户端请求
  3. 03为服务配置代理与连接池
  4. 04缓存响应并处理异步请求

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/full-stack-skills/java-skills --skill unirest-java-3

安装后在 Claude Code 中输入/unirest-java-3确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

agents/
openai.yaml
references/
caching.md
configuration.md
mocking.md
proxies.md
requests.md
responses.md

详细介绍

Unirest-Java 3.x 参考(v3.14.5)

本技能介绍适用于 Java 8+ 的 Unirest-Java 3.x HTTP 客户端库。它使用 Apache HttpClient 4 作为 HTTP 引擎,并默认包含 GSON 作为 JSON 解析器。

能力边界

✅ 擅长领域
  1. 使用流畅 API 构建 HTTP 请求(GET、POST、PUT、DELETE、PATCH)
  2. 使用内置 GSON 映射 JSON/对象(无需额外依赖)
  3. 使用 CompletableFuture 发起异步请求(通过 Apache HttpAsyncClient)
  4. 监控进度的文件上传
  5. HTTP 客户端的模拟测试
  6. 使用可配置的淘汰策略缓存响应
  7. 代理配置(简单、系统级、按请求)
  8. 用于日志记录和身份验证的请求/响应拦截器
  9. 调整连接池(concurrency(total, perRoute))
  10. 套接字超时控制(独立于连接超时)
  11. 套接字错误时自动重试(automaticRetries())
  12. 用于后台线程管理的关闭钩子
  13. 支持自定义 HostnameVerifier
⚠️ 要求
  1. Java 8 或更高版本
  2. Apache HttpClient 4(传递依赖)
  3. Maven/Gradle 依赖管理
❌ 不适用范围(及替代方案)
  1. HTTP/2 → 使用 Unirest 4.x(默认使用 HTTP/2)
  2. 通过 Unirest 使用 WebSocket → 使用 Apache HttpClient WebSocket 或专用库
  3. 服务器发送事件(SSE)→ 使用 Unirest 4.x 或自定义实现
  4. 自定义执行器支持 → 3.x 中不可用
  5. Java Authenticator 集成 → 使用 Apache 专用身份验证机制
  6. ProxySelector 支持 → 使用按请求代理或系统属性

何时使用本技能

用户需要以下功能时,请使用本技能:

  • 在 Java 8+ 项目中向 REST API 发起 HTTP 请求
  • 使用 Apache HttpClient 作为 HTTP 引擎
  • 内置 GSON,无需额外依赖
  • 调整连接池(concurrency())
  • 独立控制套接字超时
  • 在套接字错误时自动重试
  • 配置按请求代理
  • 使用自定义 HostnameVerifier

快速开始

Maven 依赖(Unirest 3.14.5):

<dependency>
    <groupId>com.konghq</groupId>
    <artifactId>unirest-java</artifactId>
    <version>3.14.5</version>
</dependency>

✅ 无需声明 JSON 模块 — 默认包含 GSON。

最简 GET 请求:

String body = Unirest.get("https://api.example.com/users")
    .asString()
    .getBody();

最简 JSON POST 请求:

HttpResponse<JsonNode> response = Unirest.post("https://api.example.com/users")
    .header("Content-Type", "application/json")
    .body(new User("Alice", "[email protected]"))
    .asJson();

关键:安装

Unirest 3.x 是单一依赖,默认包含 GSON:

<dependency>
    <groupId>com.konghq</groupId>
    <artifactId>unirest-java</artifactId>
    <version>3.14.5</version>
</dependency>

✅ 无需单独声明 JSON 模块 — 已包含基于 GSON 的 JsonObjectMapper。

关键:配置

所有配置均通过 Unirest.config() 完成:

Unirest.config()
    .connectTimeout(5000)
    .socketTimeout(10000)
    .concurrency(200, 20)
    .setDefaultHeader("Accept", "application/json")
    .setDefaultBasicAuth("user", "pass")
    .followRedirects(true)
    .verifySsl(true)
    .enableCookieManagement(true)
    .automaticRetries(true)
    .proxy("proxy.com", 8080, "user", "pass");

关键配置选项:

方法影响默认值
connectTimeout(int)连接超时(毫秒)10000
socketTimeout(int)套接字/读取超时(毫秒)60000
concurrency(int, int)最大总连接数、每个路由的最大连接数200/20
followRedirects(boolean)跟随 HTTP 重定向true
verifySsl(boolean)强制执行 SSL 验证true
enableCookieManagement(boolean)接受/存储 Cookietrue
automaticRetries(boolean)套接字错误时自动重试(最多 4 次)true
retryAfter(boolean)收到带有 Retry-After 标头的 429/529 时自动重试false
defaultBaseUrl(String)所有请求的默认基础 URL无
addShutdownHook(boolean)注册 JVM 关闭钩子false
useSystemProperties(boolean)使用代理等系统属性true

多个配置:

// Primary instance (same as static Unirest)
UnirestInstance unirest = Unirest.primaryInstance();

// Spawn a new independent instance
UnirestInstance custom = Unirest.spawnInstance();
custom.config().connectTimeout(3000);

⚠️ 如果你创建了新实例,必须自行负责将其关闭。

完整配置表、拦截器、对象映射器和指标,请参阅 references/configuration.md。

关键:发起请求

基本请求类型:

Unirest.get("http://localhost/users").asString();
Unirest.post("http://localhost/users").body(json).asJson();
Unirest.put("http://localhost/users/1").body(user).asEmpty();
Unirest.delete("http://localhost/users/1").asEmpty();

路由参数:

Unirest.get("http://localhost/users/{id}")
    .routeParam("id", "42")
    .asString();
// Results in http://localhost/users/42

查询参数:

Unirest.get("http://localhost/search")
    .queryString("q", "unirest")
    .queryString("page", 1)
    .asString();

标头和身份验证:

Unirest.get("http://localhost/protected")
    .header("X-Custom", "value")
    .basicAuth("user", "pass")
    .asString();

表单数据:

Unirest.post("http://localhost/form")
    .field("name", "Alice")
    .field("age", 30)
    .asEmpty();

文件上传:

Unirest.post("http://localhost/upload")
    .field("file", new File("/path/to/file.zip"))
    .asEmpty();

异步请求:

CompletableFuture<HttpResponse<JsonNode>> future = Unirest.get("http://localhost/data")
    .asJsonAsync(response -> {
        System.out.println(response.getBody());
    });

按请求代理(仅限 3.x):

Unirest.get("http://localhost/data")
    .proxy("proxy.com", 8080)
    .asString();

JSON Patch(RFC-6902):

Unirest.jsonPatch("http://localhost/resource")
    .add("/fruits/-", "Apple")
    .remove("/bugs")
    .replace("/name", "Updated")
    .asJson();

有关上传进度、分页请求、客户端证书等内容,请参阅 references/requests.md。

关键:处理响应

响应类型:

// String
String body = Unirest.get(url).asString().getBody();

// Object mapping (GSON included by default)
Book book = Unirest.get(url).asObject(Book.class).getBody();

// Generic types
List<Book> books = Unirest.get(url)
    .asObject(new GenericType<List<Book>>(){}).getBody();

// JSON
JsonNode json = Unirest.get(url).asJson().getBody();

// File
File file = Unirest.get(url).asFile("/tmp/download.zip").getBody();

// Empty (status/headers only)
HttpResponse resp = Unirest.delete(url).asEmpty();

错误处理:

Unirest.get("http://localhost/data")
    .asJson()
    .ifSuccess(response -> handleSuccess(response))
    .ifFailure(response -> {
        log.error("Status: " + response.getStatus());
        response.getParsingError().ifPresent(e -> {
            log.error("Parse error: " + e.getMessage());
        });
    });

解析错误:

response.getParsingError().ifPresent(ex -> {
    String originalBody = ex.getOriginalBody();
    String message = ex.getMessage();
});

映射错误对象:

HttpResponse<Book> book = Unirest.get(url).asObject(Book.class);
Error err = book.mapError(Error.class);

有关下载进度、大型响应、正文映射等内容,请参阅 references/responses.md。

关键:模拟

静态模拟:

MockClient mock = MockClient.register();

mock.expect(HttpMethod.GET, "http://api.example.com/users")
    .thenReturn("{\"name\":\"Alice\"}")
    .withStatus(200);

String body = Unirest.get("http://api.example.com/users")
    .asString().getBody();
// body == "{\"name\":\"Alice\"}"

mock.verifyAll(); // Verify all expects were called

实例模拟(3.x 要求同时注册两个客户端):

UnirestInstance unirest = Unirest.spawnInstance();
MockClient mock = MockClient.register(unirest);
// In 3.x, the mock implements both Client and AsyncClient

正文匹配:

mock.expect(HttpMethod.POST, "http://api.example.com/users")
    .body(FieldMatcher.of("name", "Alice", "role", "admin"))
    .thenReturn()
    .withStatus(201);

验证调用次数:

var expect = mock.expect(HttpMethod.GET, "http://api.example.com/users").thenReturn();
expect.verify();              // At least once
expect.verify(Times.never()); // Never called

有关 POJO 响应、多个 expect 等内容,请参阅 references/mocking.md。

关键:缓存

基本缓存:

Unirest.config().cacheResponses(true);

使用选项的高级缓存:

Unirest.config().cacheResponses(Cache.builder()
    .depth(100)                      // Max entries
    .maxAge(5, TimeUnit.MINUTES));   // Entry TTL

自定义缓存(例如 Guava):

Unirest.config().cacheResponses(
    Cache.builder().backingCache(new MyGuavaCache()));

有关自定义缓存实现的详细信息,请参阅 references/caching.md。

关键:代理

简单代理:

Unirest.config().proxy("proxy.com", 8080, "user", "pass");

逐请求代理(仅限 3.x):

Unirest.get("http://localhost/data")
    .proxy("proxy.com", 8080)
    .asString();

系统属性(3.x 中默认为 true):

System.setProperty("http.proxyHost", "localhost");
System.setProperty("http.proxyPort", "7777");
// useSystemProperties defaults to true in 3.x

有关详细信息,请参阅 references/proxies.md。

快速修复

错误原因修复方法
NoClassDefFoundError: kong/unirest/Unirest包名错误使用 import kong.unirest.*(而非 kong.unirest.core.*)
asObject() 返回 null 正文响应解析失败查看 response.getParsingError() 获取详细信息
ConnectException: Connection timed out无法访问服务或超时时间过短增大 connectTimeout 或检查网络
SocketTimeoutException超过读取超时时间增大 socketTimeout(默认值为 60000ms)
SSLHandshakeExceptionSSL 验证失败仅在开发环境使用 verifySsl(false);在生产环境修复证书
代理无法工作系统属性可能已禁用检查 useSystemProperties(true)(3.x 中默认为 true)
连接过多连接池已耗尽增大 concurrency(total, perRoute)
自动重试无法工作已禁用或不适用检查 automaticRetries(true)(默认为 true)

注意事项

  1. Java 8+ 即可满足要求 — 3.x 可在 Java 8 上运行(而 4.x 要求 Java 11+)
  2. 默认包含 GSON — 无需单独声明 JSON 模块(而 4.x 需要)
  3. 包名为 kong.unirest — 而非 kong.unirest.core(后者用于 4.x)
  4. 单个 Maven 依赖项 — unirest-java:3.14.5(而 4.x 使用 BOM + core + module)
  5. Apache HttpClient 引擎 — 使用 Apache HttpClient 4(而非 java.net.http.HttpClient)
  6. Socket 超时独立设置 — socketTimeout() 单独控制读取超时,不受 connectTimeout() 影响
  7. 连接池调优 — concurrency(total, perRoute) 可用于调优 Apache 的连接池
  8. 默认启用自动重试 — automaticRetries(true) 会针对套接字错误重试,最多 4 次
  9. 支持逐请求代理 — request.proxy(host, port) 可用(在 4.x 中已移除)
  10. 支持 HostnameVerifier — hostnameVerifier(verifier) 可用于自定义 SSL 主机名验证
  11. 提供关闭钩子 — addShutdownHook(true) 会注册 JVM 关闭钩子
  12. 默认启用系统代理属性 — useSystemProperties 默认为 true(而 4.x 中并非如此)
  13. Unirest 不支持 WebSocket — 请使用 Apache HttpClient WebSocket 或专用库
  14. 不支持 SSE — 3.x 中不存在 Unirest.sse()
  15. 模拟注册需要同时使用两个客户端 — MockClient 同时实现 Client 和 AsyncClient

参考资料

请求
  • requests.md — 路由参数、查询参数、标头、身份验证、正文类型、文件上传、上传进度、异步请求、分页请求、逐请求代理
响应
  • responses.md — asEmpty/asString/asObject/asJson/asFile、GenericType、解析错误、错误对象映射、下载进度、大型响应、错误处理
配置
  • configuration.md — 完整配置选项表、全局拦截器、多个配置、对象映射器、指标、Apache 专属选项
模拟
  • mocking.md — 静态/实例模拟、多个预期(评分)、验证、请求体匹配、表单参数、POJO 响应
缓存
  • caching.md — 基础/高级缓存、自定义缓存实现
代理
  • proxies.md — 简单代理、系统属性、按请求设置代理

评论

支持 Markdown