I have the following scenario: I set up a client which sends an aynchronous HTTP reuqest to the server. The client receives a CompletableFuture. So far evertything works fine. However, I cannot access the response of the request I am sending.
completableFuture.get().body()
rather contains the status of the request. In more detail, I am getting
{"cancelled":false,"done":true,"completedExceptionally":false,"numberOfDependents":0}
How can I get the acutal result?
Here is my code...
Rest Controller
@RestController
public class WorkerJController {
@Autowired
private WorkerJService service;
@GetMapping(value = "/JobList", produces = MediaType.APPLICATION_JSON_VALUE)
public CompletableFuture<ResponseEntity> getJobListFunction() throws JsonProcessingException, InterruptedException {
return CompletableFuture.completedFuture(service.getJobListFunction()).thenApply(ResponseEntity::ok);
}
}
Service
@Service
public class WorkerJService {
public static ArrayList<someThing> randomList = new ArrayList<>();
@Async
public CompletableFuture<String> getJobListFunction() throws JsonProcessingException, InterruptedException {
randomList.add(new someThing("abc", "dfe"));
ObjectMapper mapper = new ObjectMapper();
TimeUnit.SECONDS.sleep(5);
return CompletableFuture.completedFuture(mapper.writeValueAsString(jobList));
}
}
Async Config
@Configuration
@EnableAsync
public class AsyncConfig {
@Bean(name = "taskExecutor")
public Executor taskExecutor(){
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(3);
executor.setMaxPoolSize(3);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("AsynchThread-");
executor.initialize();
return executor;
I send the HTTP request as follows:
HttpClient client = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_1_1)
.followRedirects(HttpClient.Redirect.NORMAL)
.connectTimeout(Duration.ofSeconds(20))
.build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://localhost:8080/JobList"))
.timeout(Duration.ofMinutes(2))
.GET()
.build();
CompletableFuture<HttpResponse<String>> cf = client
.sendAsync(request, HttpResponse.BodyHandlers.ofString());
CodePudding user response:
CompletableFuture.completedFuture(service.getJobListFunction())
wraps the CompletableFuture
returned by service.getJobListFunction()
into another CompletableFuture
.
Just chain the response from the service directly with the thenApply()
instead:
@GetMapping(value = "/JobList", produces = MediaType.APPLICATION_JSON_VALUE)
public CompletableFuture<ResponseEntity> getJobListFunction() throws JsonProcessingException, InterruptedException {
return service.getJobListFunction().thenApply(ResponseEntity::ok);
}