如何获取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
相关产品推荐
相关产品推荐

