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

如何获取JSON格式货币对象并在控制器中存入List或Map集合

完全可以将批量获取的3种货币数据一次性存入List或Map集合,而且有性能更优的实现方案,不需要逐个串行发起请求。

先修正你现有代码的问题

你当前的参数映射写法是错误的,URI中定义的路径变量是{code},不是C,正确的参数传递写法应该是params.put("code", "USD"),否则会抛出路径变量找不到的异常。


两种常用实现方案

方案1:串行拉取存入List(适合对耗时不敏感的简单场景)

代码逻辑最简洁,不需要额外配置:

private final String URI_CURRENCY_PATH_ID = "http://bank.pl/api/exchangerates/rates/C/{code}";
@Autowired
RestTemplate restTemplate;

public List<Currency> getCurrencyList() {
    List<String> codeList = Arrays.asList("USD", "EUR", "GBP");
    List<Currency> resultList = new ArrayList<>();
    for (String code : codeList) {
        Map<String, String> params = new HashMap<>();
        params.put("code", code);
        Currency currency = restTemplate.getForObject(URI_CURRENCY_PATH_ID, Currency.class, params);
        if (currency != null) {
            resultList.add(currency);
        }
    }
    return resultList;
}

方案2:并行拉取存入Map(更优方案)

总耗时等于最慢的单个接口请求耗时,远低于串行拉取,且存入Map后后续可以直接通过货币编码查询对应数据,使用更方便:

private final String URI_CURRENCY_PATH_ID = "http://bank.pl/api/exchangerates/rates/C/{code}";
@Autowired
RestTemplate restTemplate;
// 线程池建议配置为Spring全局Bean,不要每次请求新建
private final ExecutorService executor = Executors.newFixedThreadPool(3);

public Map<String, Currency> getCurrencyMap() {
    List<String> codeList = Arrays.asList("USD", "EUR", "GBP");
    Map<String, Currency> resultMap = new ConcurrentHashMap<>();
    List<Future<Currency>> futureList = new ArrayList<>();

    // 批量提交异步请求
    for (String code : codeList) {
        futureList.add(executor.submit(() -> {
            Map<String, String> params = new HashMap<>();
            params.put("code", code);
            return restTemplate.getForObject(URI_CURRENCY_PATH_ID, Currency.class, params);
        }));
    }

    // 收集返回结果
    for (int i = 0; i < codeList.size(); i++) {
        try {
            Currency currency = futureList.get(i).get(3, TimeUnit.SECONDS); // 超时控制
            if (currency != null) {
                resultMap.put(codeList.get(i), currency);
            }
        } catch (InterruptedException | ExecutionException | TimeoutException e) {
            // 自定义异常处理逻辑,比如日志打印、降级返回
            e.printStackTrace();
        }
    }
    return resultMap;
}

如果是Spring Boot 2.x+的项目,更推荐用WebClient实现响应式批量拉取,资源占用更低,代码更简洁:

private final WebClient webClient = WebClient.create("http://bank.pl/api/exchangerates/rates/C");

public Map<String, Currency> getCurrencyMapReactive() {
    List<String> codeList = Arrays.asList("USD", "EUR", "GBP");
    return Flux.fromIterable(codeList)
            .flatMap(code -> webClient.get()
                    .uri("/{code}", code)
                    .retrieve()
                    .bodyToMono(Currency.class)
                    .map(currency -> Tuples.of(code, currency)))
            .collectMap(Tuple2::getT1, Tuple2::getT2)
            .block(Duration.ofSeconds(3));
}

注意事项

你需要先定义和JSON返回结构匹配的实体类:

  • Currency类包含table、currency、code、rates四个属性,其中rates是List类型
  • Rate类包含no、effectiveDate、bid、ask四个属性
    否则会出现JSON反序列化失败的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 02:15:01