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
相关产品推荐
相关产品推荐

