TV *_*ath 6 java spring multithreading future asyncresttemplate
我必须使用RestTemplate多次使用不同的参数进行Rest API调用.API是相同的,但它是正在改变的参数.次数也是可变的.我想使用AsyncRestTemplate但我的主线程应该等到所有API调用都成功完成.我还想处理每个API调用返回的响应.目前我正在使用RestTemplate.基本形式如下.
List<String> listOfResponses = new ArrayList<String>();
for (Integer studentId : studentIdsList) {
String respBody;
try {
ResponseEntity<String> responseEntity = restTemplate.exchange(url, method, requestEntity, String.class);
} catch (Exception ex) {
throw new ApplicationException("Exception while making Rest call.", ex);
}
respBody = requestEntity.getBody();
listOfResponses.add(respBody);
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下如何实现AsyncRestTemplate?
Did*_*r L 10
使用AsyncRestTemplate(或实际上是任何异步API)时的主要想法是在第一时间发送所有请求,保留相应的未来,然后再次处理所有响应.您只需使用2个循环即可完成此操作:
List<ListenableFuture<ResponseEntity<String>>> responseFutures = new ArrayList<>();
for (Integer studentId : studentIdsList) {
// FIXME studentId is not used
ListenableFuture<ResponseEntity<String>> responseEntityFuture = restTemplate.exchange(url, method, requestEntity, String.class);
responseFutures.add(responseEntityFuture);
}
// now all requests were send, so we can process the responses
List<String> listOfResponses = new ArrayList<>();
for (ListenableFuture<ResponseEntity<String>> future: responseFutures) {
try {
String respBody = future.get().getBody();
listOfResponses.add(respBody);
} catch (Exception ex) {
throw new ApplicationException("Exception while making Rest call.", ex);
}
}
Run Code Online (Sandbox Code Playgroud)
注意:如果您需要将响应与原始请求配对,则可以使用映射或请求+响应对象列表替换期货列表.
我还注意到studentId你的问题没有使用.
如果对您来说可行,您可以使用 Java 8 Stream API:
List<String> listOfResponses = studentIdsList.stream()
.parrallel()
.map({studentId ->
ResponseEntity<String> responseEntity = restTemplate.exchange(url, method, studentId, String.class);
return responseEntity.getBody();
})
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
这段代码基本上会执行两件事:
更新:同意@Didier L - 当您需要执行大量请求时,此解决方案可能无法正常工作。这是一个更新的版本:
List<String> listOfResponses = studentIdsList.stream()
.map(studentId -> asyncRestTemplate.exchange(url, method, studentId, String.class)
.collect(Collectors.toList()).stream()
.map(this::retrieveResult)
.collect(Collectors.toList());
/**
* Retrieves results of each request by blocking the main thread. Note that the actual request was performed on the previous step when
* calling asyncRestTemplate.exchange(url, method, studentId, String.class)
*/
private String retrieveResult(ListenableFuture<ResponseEntity<String>> listenableFuture) {
try {
return listenableFuture.get().getBody();
} catch (Exception e) {
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8836 次 |
| 最近记录: |