You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java如何实现并行HTTP GET请求并将多请求结果合并为JSONObject

优化实现思路
  • 替换同步HTTP客户端为异步版本:你当前用的是同步Apache HttpClient,每个请求都会阻塞等待返回,60个请求的耗时是所有请求耗时的累加值。可以改用支持异步的HTTP客户端,比如Java 11+内置的HttpClient、OkHttp或者Apache Async HttpClient,异步请求不会阻塞当前线程,可同时发起多个请求,总耗时近似于单个请求的最长耗时。
  • 用CompletableFuture管理批量异步任务:拿到总页数后,把每个页码的请求都封装成独立的CompletableFuture异步任务,全部提交后调用CompletableFuture.allOf()等待所有任务执行完成,再统一把结果汇总到JSONObject中,不需要循环逐个等待请求返回。
  • 抽离公共请求逻辑:把重复的HTTP请求、响应解析逻辑抽成单独的工具方法,入参为页码,出参为对应页的JSONArray,不用复制粘贴多份代码,后续修改请求配置也只需调整一处。
  • 控制并发量级:不要一次性发起全部60个请求,可将并发数控制在10~20之间,避免触发目标API的限流规则导致请求失败,可以通过自定义线程池的核心线程数,或者用Semaphore信号量实现并发数管控。
学习指引
  • 先掌握Java并发基础组件:重点学习线程池、CompletableFuture的常用API,不需要一开始深入底层原理,先能跑通基础的异步任务、多任务合并等待逻辑即可。
  • 再学习异步HTTP客户端的基础用法:选择一款异步HTTP客户端,从单个异步GET请求的示例开始跑通,再扩展到批量请求的场景。
  • 最后补充异常处理逻辑:给请求增加超时配置、失败重试、异常捕获逻辑,避免单个页请求失败导致整个数据拉取任务崩溃。
简化优化示例代码(基于Java 11+ 内置HttpClient)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import org.json.JSONArray;
import org.json.JSONObject;

public class PageFetcher {
    private static final String BASE = "https://someapi.com/api?page=";
    // 全局复用HttpClient,不用每次请求新建
    private static final HttpClient HTTP_CLIENT = HttpClient.newHttpClient();

    // 抽离单页请求逻辑
    private static CompletableFuture<JSONArray> getPageData(int page) {
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(BASE + page))
                .timeout(java.time.Duration.ofSeconds(10)) // 配置10秒超时
                .build();
        // 异步发送请求,解析返回结果
        return HTTP_CLIENT.sendAsync(request, HttpResponse.BodyHandlers.ofString())
                .thenApply(response -> new JSONObject(response.body()).getJSONArray("data"));
    }

    public static String getData() throws Exception {
        JSONObject finalData = new JSONObject();
        // 先同步拉取第一页拿到总页数
        HttpRequest firstPageReq = HttpRequest.newBuilder()
                .uri(URI.create(BASE + 0))
                .timeout(java.time.Duration.ofSeconds(10))
                .build();
        HttpResponse<String> firstResp = HTTP_CLIENT.send(firstPageReq, HttpResponse.BodyHandlers.ofString());
        JSONObject firstJson = new JSONObject(firstResp.body());
        int pages = firstJson.getInt("totalPages");
        finalData.put("0", firstJson.getJSONArray("data"));

        // 提交剩余页的异步请求
        List<CompletableFuture<Void>> taskList = new ArrayList<>();
        for (int x = 1; x < pages; x++) {
            int pageNum = x;
            CompletableFuture<Void> task = getPageData(pageNum)
                    .thenAccept(data -> finalData.put(String.valueOf(pageNum), data));
            taskList.add(task);
        }

        // 等待所有异步请求完成
        CompletableFuture.allOf(taskList.toArray(new CompletableFuture[0])).join();
        return finalData.toString();
    }
}

内容的提问来源于stack exchange,提问作者nicholxs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 17:36:03