版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jiangchao858/article/details/86709750
如果你是第一次看到这篇文章,那么我建议你先去看一下上一篇《Spring 的异步HTTP请求AsyncRestTemplate》
还是那个套路
熟悉使用RestTemplate
的,不会觉得AsyncRestTemplate
很难,因为的确很相似。在Spring 看来,你只管写同步的代码,异步的执行交给它处理就可以了。
配置依旧在
默认的有时难以满足多变的需求,于是配置自定义参数排上用场:
@Bean
public AsyncRestTemplate asyncRestTemplate() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
//设置链接超时时间
factory.setConnectTimeout(100);
//设置读取资料超时时间
factory.setReadTimeout(200);
//设置异步任务(线程不会重用,每次调用时都会重新启动一个新的线程)
factory.setTaskExecutor(new SimpleAsyncTaskExecutor());
return new AsyncRestTemplate(factory);
}
- 设置合理的超时时间对于HTTP请求至关重要,单位为毫秒
- 异步任务可能需要配置线程池
化繁为简
如果需要对异步请求的返回值做处理,需要手动实现回调,而在回调里面实现逻辑看起来会很臃肿。
entity.addCallback(new SuccessCallback<ResponseEntity<String>>() {
@Override
public void onSuccess(ResponseEntity<String> result) {
log.info("A");
}
}, new FailureCallback() {
@Override
public void onFailure(Throwable ex) {
log.info("B");
}
});
这时如果能用上Java 8 的lambda表示式,代码可以如此简单:
public String demo3() {
String url = "http://localhost:8080/teacher/1";
log.info("Start");
ListenableFuture<ResponseEntity<Teacher>> entity = asyncRestTemplate.getForEntity(url, Teacher.class);
entity.addCallback(result -> log.info(result.getBody().getName()),(e) -> log.error(e.getMessage()));
log.info("C");
return "End";
}
一行代码可以替代之前的十多行,代码更整洁了,可读性可高了不少。
为了能证明之前设置的超时时间有效,我在需要调用的请求代码中加入一行:
TimeUnit.SECONDS.sleep(3);
// 暂停3秒
调用demo3(),查看控制台:
22:36:29.844 INFO 2732 --- [nio-8080-exec-1] c.c.t.web.AsyncTeacherController : Start
22:36:29.926 INFO 2732 --- [nio-8080-exec-1] c.c.t.web.AsyncTeacherController : C
22:36:29.926 INFO 2732 --- [nio-8080-exec-1] c.c.t.web.AsyncTeacherController : End
22:36:30.132 ERROR 2732 --- [cTaskExecutor-1] c.c.t.web.AsyncTeacherController : Read timed out
回调函数的第一个参数是成功以后执行的代码,没有在控制台看到相关信息,说明没有执行。
最后一行的输出不是来自主线程,并且打印的是错误信息:超时。
异步发送数据
我已经实现了一个接受数据的HTTP接口:
@PostMapping("/save/teacher")
public Teacher save(@RequestBody Teacher teacher){
log.info(teacher.toString());
return teacher;
}
发送数据的逻辑,需要使用到 POST 请求:
public String demo4() {
String url = "http://localhost:8080/save/teacher";
//设置Header
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add("Content-Type", "application/json;charset=UTF-8");
HttpEntity<Object> httpEntity = new HttpEntity<>(headers);
Teacher teacher = new Teacher().setId(4).setName("Kelly");
//异步发送
ListenableFuture<ResponseEntity<Teacher>> entity = asyncRestTemplate.postForEntity(url, httpEntity, Teacher.class, teacher);
entity.addCallback(result -> log.info(result.getBody().getName()),(e) -> log.error(e.getMessage()));
log.info("C");
return "End";
}