mcpField
U
unirest-java-4

unirest-java-4

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

关于 unirest-java-4

面向 Java 开发者的 Unirest-Java 4.x 使用参考,涵盖 HTTP 请求、响应处理、流式通信、配置与测试。适用于 Java 11 及以上版本。

主要功能

  1. 01流畅式 HTTP 请求
  2. 02使用 GSON 或 Jackson 映射 JSON
  3. 03通过 CompletableFuture 异步请求
  4. 04支持 SSE 和 WebSocket
  5. 05HTTP 响应缓存
  6. 06模拟 HTTP 客户端测试

适用场景

  1. 01在 Java 中调用 REST API
  2. 02通过 HTTP 上传或下载文件
  3. 03消费服务器发送事件
  4. 04在单元测试中模拟 HTTP 调用

安装

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

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

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

包含的文件

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

agents/
openai.yaml
references/
caching.md
configuration.md
mocking.md
proxies.md
requests.md
responses.md
sse.md
upgrade-guide.md
websocket.md

详细介绍

Unirest-Java 4.x 参考(v4.10.0)

本技能涵盖适用于 Java 11+ 的 Unirest-Java 4.x HTTP 客户端库。它使用内置的 java.net.http.HttpClient(取代 3.x 中的 Apache HttpClient),并默认使用 HTTP/2。

能力范围

✅ 擅长领域
  1. 使用流畅 API 构建 HTTP 请求(GET、POST、PUT、DELETE、PATCH)
  2. 使用 GSON 或 Jackson 进行 JSON/对象映射(必须显式声明模块)
  3. 使用 CompletableFuture 发送异步请求(内置于 java.net.http.HttpClient)
  4. 上传文件并监控进度
  5. 通过 Unirest.sse(url) 接收 Server-Sent Events(SSE)
  6. 通过 Unirest.webSocket(url) 建立 WebSocket 连接
  7. 对 HTTP 客户端进行模拟测试
  8. 配置响应缓存的淘汰策略
  9. 代理配置(简单代理、系统代理、ProxySelector)
  10. 默认使用 HTTP/2(可通过 config.version() 配置)
  11. 通过 config.executor() 支持自定义执行器
  12. 支持 Java Authenticator
⚠️ 要求
  1. Java 11 或更高版本(使用 java.net.http.HttpClient)
  2. 必须声明 JSON 模块(unirest-modules-gson 或 unirest-modules-jackson)以进行对象映射
  3. 使用 BOM 管理 Maven/Gradle 依赖
❌ 不支持的范围(替代方案)
  1. 每个请求单独配置代理 → 使用全局 Unirest.config().proxy()(已在 4.x 中移除)
  2. 自定义 HostnameVerifier → 使用 disableHostNameVerification() 系统属性
  3. 独立于连接超时的套接字超时 → 改用 requestTimeout()
  4. 调整连接池参数(concurrency(total, perRoute))→ 不支持(由 java.net.http 管理)
  5. 套接字错误时自动重试 → 仅对 429/529 使用 retryAfter()
  6. 关闭钩子 → 无需配置(没有需要管理的后台线程)
  7. 集成 Apache HttpClient → 如需 Apache 专属功能,请使用 3.x

何时使用本技能

当用户需要以下操作时,请使用本技能:

  • 在 Java 中向 REST API 发送 HTTP 请求
  • 通过 HTTP 上传或下载文件
  • 接收 Server-Sent Event 流
  • 在单元测试中模拟 HTTP 调用
  • 配置 HTTP 请求的代理
  • 缓存 HTTP 响应
  • 从 Unirest 3.x 迁移到 4.x

快速入门

Maven 依赖(Unirest 4.10.0):

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.konghq</groupId>
            <artifactId>unirest-java-bom</artifactId>
            <version>4.10.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>com.konghq</groupId>
        <artifactId>unirest-java-core</artifactId>
    </dependency>
    
    <dependency>
        <groupId>com.konghq</groupId>
        <artifactId>unirest-modules-gson</artifactId>
    </dependency>
</dependencies>

最简 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 4 采用模块化设计。必须声明:

  1. unirest-java-core — HTTP 客户端引擎
  2. JSON 模块 — unirest-modules-gson 或 unirest-modules-jackson(对象映射/JSON 解析必需)

⚠️ 如果没有 JSON 模块,调用 asObject()、asJson() 和 JSON Patch 将在运行时失败。

完整安装详情请参阅 references/configuration.md。

重要:配置

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

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

主要配置选项:

方法影响默认值
connectTimeout(int)连接超时(ms)10000
requestTimeout(int)请求超时infinite
followRedirects(boolean)跟随 HTTP 重定向true
verifySsl(boolean)强制执行 SSL 验证true
enableCookieManagement(boolean)接受/存储 Cookietrue
retryAfter(boolean)对 429/529 自动重试false
defaultBaseUrl(String)所有请求的默认基础 URLnone

多套配置:

// 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());
    });

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

重要:服务器发送事件(SSE)

异步消费 SSE:

var future = Unirest.sse("https://stream.example.com/events")
    .connect(event -> {
        var data = event.asObject(MyEvent.class);
        System.out.println("Event: " + data.getTitle());
    });

同步消费 SSE:

Unirest.sse("https://stream.example.com/events")
    .connect()
    .map(event -> event.asObject(MyEvent.class))
    .forEach(data -> System.out.println("Event: " + data.getTitle()));

⚠️ SSE 连接会一直保持。生产系统中请使用异步模式。 ⚠️ 对象映射需要配置 ObjectMapper。

完整详情请参阅 references/sse.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。

重要:模拟

静态模拟:

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

实例模拟:

UnirestInstance unirest = Unirest.spawnInstance();
MockClient mock = MockClient.register(unirest);

请求体匹配:

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().proxy("proxy.com", 8080, "user", "pass");

系统属性:

System.setProperty("http.proxyHost", "localhost");
System.setProperty("http.proxyPort", "7777");
Unirest.config().useSystemProperties(true);

多个代理(ProxySelector):

Unirest.config()
    .proxy(new ProxySelector() {
        @Override
        public List<Proxy> select(URI uri) {
            if (uri.getHost().equals("internal.com")) {
                return List.of(new Proxy(HTTP,
                    InetSocketAddress.createUnresolved("internal-proxy.com", 8080)));
            }
            return List.of(new Proxy(HTTP,
                InetSocketAddress.createUnresolved("default-proxy.com", 8080)));
        }
        @Override
        public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {}
    });

有关 Authenticator 设置和详情,请参阅 references/proxies.md。

重要:WebSocket

连接到 WebSocket:

Unirest.webSocket("ws://localhost/socket")
    .connect(ws -> {
        ws.sendText("Hello!");
        ws.onMessage(message -> {
            System.out.println("Received: " + message);
        });
    });

使用 POJO 映射的 WebSocket:

Unirest.webSocket("ws://localhost/events")
    .connect(ws -> {
        ws.onMessage(event -> {
            MyEvent data = event.asObject(MyEvent.class);
            processEvent(data);
        });
    });

⚠️ WebSocket 仅支持 4.x,不适用于 3.x。

完整详情请参阅 references/websocket.md。

快速修复

错误原因修复方法
NoClassDefFoundError: JsonObject缺少 JSON 模块添加 unirest-modules-gson 或 unirest-modules-jackson 依赖
java.lang.NoClassDefFoundError: kong/unirest/Unirest4.x 中的包名错误将导入从 kong.unirest.* 改为 kong.unirest.core.*
asObject() 返回的响应体为 null响应解析失败检查 response.getParsingError() 获取详情
ConnectException: Connection timed out服务器无法访问或超时时间过短增大 connectTimeout 或检查网络
SSLHandshakeExceptionSSL 验证失败仅在开发环境中使用 verifySsl(false),并在生产环境中修复证书
Host header override not allowedJava 11+ HttpClient 限制设置系统属性 jdk.httpclient.allowRestrictedHeaders=host
4.x 中代理无法使用4.x 默认禁用系统属性显式调用 useSystemProperties(true)

注意事项

  1. 必须使用 Java 11+ — Unirest 4.x 使用 java.net.http.HttpClient,无法在 Java 8 上运行
  2. 必须声明 JSON 模块 — 与 3.x 不同,4.x 没有默认 JSON 解析器。若未使用 unirest-modules-gson 或 unirest-modules-jackson,JSON 解析将在运行时失败
  3. 包名重命名 — kong.unirest(3.x)→ kong.unirest.core(4.x),JSON 模块位于 kong.unirest.modules.gson/jackson(4.3+)
  4. 默认使用 HTTP/2 — 4.x 默认使用 HttpClient.Version.HTTP_2。使用 config.version(HttpClient.Version.HTTP_1_1) 可降级
  5. 不支持单请求代理 — 3.x 允许使用 request.proxy(host, port)。4.x 仅支持通过 Unirest.config().proxy() 设置全局代理
  6. 没有 socketTimeout — 3.x 有独立的 socketTimeout()。4.x 使用 requestTimeout(),涵盖整个请求生命周期
  7. 不支持并发调优 — concurrency(total, perRoute) 是 Apache 专属功能。java.net.http 在内部管理连接池
  8. 不支持自动重试 — automaticRetries(true) 是 Apache 专属功能。4.x 仅对 429/529 响应提供 retryAfter()
  9. 没有 HostnameVerifier — 3.x 有 hostnameVerifier(verifier)。4.x 使用 disableHostNameVerification() 系统属性(作用于整个 JVM)
  10. 默认禁用系统代理属性 — 与 3.x(默认为 true)不同,4.x 的 useSystemProperties 默认为 false
  11. SSE 和 WebSocket 仅支持 4.x — 3.x 中不存在 Unirest.sse() 和 Unirest.webSocket()
  12. 简化了 Mock 注册 — 3.x:MockClient.register() 要求调用 .httpClient(client).asyncClient(client)。4.x:只需调用 .httpClient(client)
  13. 配置更改需要重置 — Unirest 激活后,更改客户端创建配置前必须先调用 config().reset()
  14. 已移除 isRunning() — 3.x 有 Unirest.isRunning()。4.x 已将其移除(没有需要监控的后台线程)

参考资料

请求
  • requests.md — 路由参数、查询参数、请求头、身份验证、正文类型、文件上传、上传进度、异步请求、分页请求、客户端证书
响应
  • responses.md — asEmpty/asString/asObject/asJson/asFile、GenericType、解析错误、错误对象映射、下载进度、大型响应、错误处理
配置
  • configuration.md — 完整配置选项表、全局拦截器、多种配置、对象映射器(Jackson/GSON)、指标
Mock
  • mocking.md — 静态/实例 Mock、多个期望(评分)、验证、正文匹配、表单参数、POJO 响应
缓存
  • caching.md — 基础/高级缓存、自定义缓存实现
服务器推送事件
  • sse.md — SSE 异步/同步消费、对象映射要求
WebSocket
  • websocket.md — WebSocket 连接、消息处理、POJO 映射
代理
  • proxies.md — 简单代理、系统属性、带 Authenticator 的 ProxySelector
升级指南
  • upgrade-guide.md — 从 3.x 迁移到 4.x、包名重命名、Maven 坐标变更、行为差异

评论

支持 Markdown