CompletableFuture.get()返回状态而非响应体,如何获取实际结果?
问题原因
你的服务器端代码存在嵌套CompletableFuture的错误:
- Service层的
getJobListFunction()已经返回CompletableFuture<String>,但Controller层错误地用CompletableFuture.completedFuture()将其再次包装,导致最终返回的ResponseEntity的body是CompletableFuture对象本身,而不是异步执行后的业务数据。客户端收到的就是这个CompletableFuture对象序列化后的JSON(即你看到的{"cancelled":false,...})。
修复步骤
1. 修复Rest Controller代码
去掉多余的CompletableFuture.completedFuture()包装,直接对Service返回的CompletableFuture<String>进行链式处理:
@RestController public class WorkerJController { @Autowired private WorkerJService service; @GetMapping(value = "/JobList", produces = MediaType.APPLICATION_JSON_VALUE) public CompletableFuture<ResponseEntity<String>> getJobListFunction() { // 直接基于Service返回的CompletableFuture进行处理,避免嵌套 return service.getJobListFunction() .thenApply(ResponseEntity::ok); } }
注意:方法返回值改为
CompletableFuture<ResponseEntity<String>>,明确泛型类型,避免类型擦除导致的问题。
2. 修复Service层代码
修正代码中的变量名笔误(jobList应为randomList),并移除不必要的异常声明(CompletableFuture会自动捕获异步执行中的异常):
@Service public class WorkerJService { public static ArrayList<someThing> randomList = new ArrayList<>(); @Async("taskExecutor") // 指定自定义的线程池,确保@Async生效 public CompletableFuture<String> getJobListFunction() { randomList.add(new someThing("abc", "dfe")); ObjectMapper mapper = new ObjectMapper(); try { TimeUnit.SECONDS.sleep(5); return CompletableFuture.completedFuture(mapper.writeValueAsString(randomList)); } catch (JsonProcessingException | InterruptedException e) { return CompletableFuture.failedFuture(e); } } }
补充:给
@Async指定线程池名称taskExecutor,确保Spring使用你自定义的线程池执行异步任务。
3. 验证客户端代码
客户端代码本身没有问题,修复服务器端后,调用cf.get().body()即可获取实际的业务响应JSON:
// 等待异步请求完成并获取响应体 String responseBody = cf.get().body(); System.out.println(responseBody); // 输出实际的列表JSON
内容的提问来源于stack exchange,提问作者Shakesbeer
相关产品推荐
相关产品推荐

