我有一个具有端点的休息控制器:@GET@Path("/reindex-record")public String reindexRecord(@QueryParam("id") String id) { if (StringUtils.isEmpty(id)) { CompletableFuture.runAsync( () -> runWithException(Reindexer::reindexAll)); } else { CompletableFuture.runAsync(() -> runWithException( () -> Reindexer.reindexOne(id))); } // return "ok" or throw WebApplciationException from runWithException method below}这是我的包装方法 - 两种方法 - reindexAll 和 reindexOne 抛出检查异常所以决定使用包装方法和接口:public interface RunnableWithException { void run() throws Exception; }private void runWithException(RunnableWithException task) { try { task.run(); } catch (Exception e) { log.error("Error occured during async task execution", e); throw new WebApplicationException( Response.status(Response.Status.INTERNAL_SERVER_ERROR) .entity("Internal error occurred").build()); }}问题是我想使用 CompleteableFuture 不定时地运行这个任务,并且只有在给定的任务完成后或者如果有错误抛出 WebApplicationException 和 INTERNAL_SERVER_ERROR 状态时才给出响应。你将如何在我的用例中使用 if/else 来实现它?编辑:截至目前我有这个方法:@GET@Path("/reindex-record")public String reindexRecord(@QueryParam("id") String id) throws ExecutionException, InterruptedException { CompletableFuture<Void> task; if (StringUtils.isEmpty(id)) { task = CompletableFuture.runAsync( () -> runWithException(Reindexer::reindexAll)); } else { task = CompletableFuture.runAsync(() -> runWithException( () -> Reindexer.reindexOne(id))); }而不是在我的exceptionally块中定义的 503 。如果重要的话,将 dropwizard 与 JAX-RS 一起使用。
2 回答
慕村225694
TA贡献1880条经验 获得超4个赞
您可以将方法的主体更改为:
@GET
@Path("/reindex-record")
public String reindexRecord(@QueryParam("id") String id) {
final CompletableFuture<Void> future;
if (StringUtils.isEmpty(id)) {
future = CompletableFuture.runAsync(
() -> runWithException(Reindexer::reindexAll));
} else {
future = CompletableFuture.runAsync(
() -> runWithException(() -> Reindexer.reindexOne(id)));
}
// this will block
future.get();
return "ok";
}
通过存储未来,您可以调用其get()上的方法,该方法将阻塞直到未来完成。
来自 的javadoc CompletableFuture.get():
如有必要,等待此未来完成,然后返回其结果。
添加回答
举报
0/150
提交
取消