【问题标题】:CompletableFuture - Run multiple rest calls throwing java.util.concurrent.CompletionExceptionCompletableFuture - 运行多个抛出 java.util.concurrent.CompletionException 的 rest 调用
【发布时间】:2021-09-27 16:26:53
【问题描述】:

我有一个服务对另一个服务进行 2 次调用,然后合并响应并生成响应。

public HashMap<String,Double> getResp(String requestJson, double defaultScore, String anomalySelfInclUrl,String anomalySelfExclUrl){
        CompletableFuture<Double> f1 = getHelper(requestJson,anomalySelfInclUrl);
        CompletableFuture <Double>f2=  getHelper(requestJson,anomalySelfExclUrl);
        AnomalyResponse anomalyResponse =new AnomalyResponse();
        HashMap<String,Double> respMap= new HashMap<>();
        CompletableFuture.allOf(f1,f2)
                .thenRun(() -> {
                    try {
                        Double anomalySelfModelRes = f1.get();
                        Double anomalyExclModelRes = f2.get();
                        respMap.put(Constants.selfInc,anomalySelfModelRes);
                        respMap.put(Constants.selfExcl,anomalyExclModelRes);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }).join();
        return respMap;
    }

public CompletableFuture<Double> getHelper(String requestJson, String url)  {
        return CompletableFuture.supplyAsync(() -> {
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            HttpEntity<String> entity = new HttpEntity<>(requestJson, headers);
            String resp =restTemplate.postForObject(url, entity, String.class);
            JsonObject json = new JsonParser().parse(resp).getAsJsonObject();
            return json.get("score").getAsDouble();
        });

    }

在 getResp 方法中,我使用可完成的未来创建 2 个 post 调用(通过 getHelper 方法)。 一旦两个 post 调用都完成,我会将它们添加到 HashMap 并返回它。 但我在 postForObject() 方法中收到以下错误。

org.jboss.resteasy.spi.UnhandledException: java.util.concurrent.CompletionException

错误似乎正在发生,因为被调用的服务没有接收到发布的 json 数据和标头(包装在 HttpEntity 中)。 这怎么会发生?该问题在连续调用期间不会出现。

【问题讨论】:

  • 假设您检查了相同的代码是否按顺序运行(即不使用异步期货)。如果是,则必须确认传递的 restTemplate 是否确实导致了问题(它不应该因为实例是线程安全的),否则,还有另一个嵌套异常,被 CompletableFuture 吞没,没有安全捕获。跨度>

标签: java spring-boot completable-future


【解决方案1】:

如果在compleable future内执行方法时发生异常,则抛出完成异常。

假设您从 API 获得 401,而您的 restTemplate 将引发未经授权的异常。它将被包装在 CompletionException 中。

您可以从objOfCompletionException.getCause() 方法调用中获得实际响应。它将包含实际发生异常的所有详细信息。

【讨论】:

  • 我现在已经更新了问题。似乎发布的 HttpEntity 在被调用的服务端没有收到
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-07-11
  • 1970-01-01
  • 2017-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-07
相关资源
最近更新 更多