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

Play Framework 2.6:解决CompletionStage获取JsonObject的get方法报错

解决CompletionStage无法调用get(int)的问题

你遇到的编译错误根源很明确:CompletionStage接口本身并没有定义get(int)方法——这个方法属于java.util.concurrent.Future接口,而CompletionStage是Java 8引入的更抽象的异步任务契约,和Future属于不同的API体系,直接调用自然会报错。

下面给你两种可行的解决思路,其中第二种更贴合Play框架的异步非阻塞设计理念:

方案一:转换为Future后同步获取(快速修复编译问题)

如果只是想快速解决编译错误,可以把CompletionStage转换成CompletableFuture(它实现了Future接口),再调用get方法。建议指定时间单位,让代码语义更清晰:

JsonObject request = HttpRequestProcessor.getJsonFromRequest(request().body());
ActorRef actorRef = ActorHandler.getActorReferenceOfParameterisedActor(AControllerTasksExecutor.class, new AControllersTaskContext(FactoryType.USER_COMMAND_FACTORY, ObjectType.PURCHASE_SHARES));
CompletionStage<JsonObject> promise = PromiseHandler.getPromise(actorRef, request, 7000);
JsonObject response = null;
Result result = null;
try {
    // 将CompletionStage转换为CompletableFuture,调用带时间单位的get方法
    CompletableFuture<JsonObject> future = promise.toCompletableFuture();
    response = future.get(70000, TimeUnit.MILLISECONDS);
    log.debug(">> response object >> {}", response);
    result = PlayResultHandler.getResult(response.get("status").getAsInt(), JsonHandler.parseJsonIntoString(response));
} catch (Exception e) {
    // 务必补充异常处理逻辑,比如打印错误日志或返回错误响应
    log.error("Failed to retrieve async response", e);
}

⚠️ 注意:这种同步阻塞的方式在Play框架中并不推荐,因为它会占用请求线程,降低系统的并发处理能力,违背了Play异步非阻塞的设计初衷。

方案二:使用CompletionStage的异步API(推荐)

Play框架本身基于异步非阻塞架构构建,更好的做法是利用CompletionStage的链式异步方法(比如thenApply、exceptionally)来处理结果,完全避免线程阻塞:

JsonObject request = HttpRequestProcessor.getJsonFromRequest(request().body());
ActorRef actorRef = ActorHandler.getActorReferenceOfParameterisedActor(AControllerTasksExecutor.class, new AControllersTaskContext(FactoryType.USER_COMMAND_FACTORY, ObjectType.PURCHASE_SHARES));
CompletionStage<JsonObject> promise = PromiseHandler.getPromise(actorRef, request, 7000);

// 异步链式处理结果与异常
CompletionStage<Result> resultStage = promise.thenApply(response -> {
    log.debug(">> response object >> {}", response);
    return PlayResultHandler.getResult(response.get("status").getAsInt(), JsonHandler.parseJsonIntoString(response));
}).exceptionally(e -> {
    // 统一处理异步过程中的异常
    log.error("Error processing async response", e);
    return internalServerError(JsonHandler.parseJsonIntoString(new JsonObject().addProperty("error", e.getMessage())));
});

// 在Play控制器中,直接返回CompletionStage<Result>即可,框架会自动处理异步结果
return resultStage;

额外优化建议

你的PromiseHandler类中,CompletionStage.wrap(ask(...))可以简化——Akka的ask方法本身就返回CompletionStage,不需要额外包装:

public class PromiseHandler {
    private final static Logger log = LoggerFactory.getLogger(PromiseHandler.class);
    public static <B> CompletionStage<B> getPromise(ActorRef actorRef, Object msg, int time) {
        log.debug("Preparing promise. ActorRef: {}, Message-Object: {}, time: {}", actorRef, msg, time);
        return ask(actorRef, msg, time)
                .thenApply(response -> {
                    log.debug("In Apply method. Returning Response. Response-object: {}",response);
                    return (B) response;
                });
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:26:41