How configure spring to work with CompletionStage
return types? Consider a code:
@RequestMapping(path = "/", params = "p", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public CompletionStage<List<MyResult>> search(@RequestParam("p") String p) {
CompletionStage<List<MyResult>> results = ...
return results;
}
I got 404, but I see in log that method is triggered. If I change signature like that:
@RequestMapping(path = "/", params = "p", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public List<MyResult> search(@RequestParam("p") String p) {
CompletionStage<List<MyResult>> results = ...
return results.get();
}
I see successfull json array.
How to make CompletionStage
works with spring (4.2.RELEASE)?
UPDATED
For test I wrote following methods:
@RequestMapping(path = "/async")
@ResponseBody
public CompletableFuture<List<MyResult>> async() {
return CompletableFuture.completedFuture(Arrays.asList(new MyResult("John"), new MyResult("Bob")));
}
And it works. Oo
I have test this version of future:
@RequestMapping(path = "/async2")
@ResponseBody
public CompletableFuture<List<MyResult>> async2() {
AsyncRestTemplate template = new AsyncRestTemplate();
//simulate delay future with execution delay, you can change url to another one
return toCompletable(template.getForEntity("https://www.google.ru/?gws_rd=ssl#q=1234567890-", String.class))
.thenApply(
resp -> template.getForEntity("https://www.google.ru/?gws_rd=ssl#q=1234567890-", String.class))
.thenApply(
resp -> template.getForEntity("https://www.google.ru/?gws_rd=ssl#q=1234567890-", String.class))
.thenApply(
resp -> template.getForEntity("https://www.google.ru/?gws_rd=ssl#q=1234567890-", String.class))
.thenApply(
resp -> template.getForEntity("https://www.google.ru/?gws_rd=ssl#q=1234567890-", String.class))
.thenApply(
resp -> template.getForEntity("https://www.google.ru/?gws_rd=ssl#q=1234567890-", String.class))
.thenApply(resp -> Arrays.asList(new MyResult("John"), new MyResult("Bob")));
}
A bit agly, but ... works!
So my original method has the following logic:
- Iterate over Collection
- Make async call via AsyncRestTemplate for each collection element
- Make call to each CompletableFuture in collection
thenApply
(transform result)thenCompose
(make new async call with AsyncRestTemplate)thenApply
(transform result)- At the end I call transform List to Completable as described here.
It seem that Future transformation is wrong. Can it be that future chain eecutes too long? Any ideas?