[英]How to catch exceptions with the CompletableFuture class in REST web services and Spring?
我已经使用Spring框架和REST开发了一些异步Web服务,我从使用Spring类AsyncRestTemplate
创建的客户端中使用了它。 类返回一个对象ListenableFuture<ResponseEntity<T>>
(使用getForEntity
方法),该对象将带来Web服务返回的值(使用.get():<T>
)。 它工作正常,但是在REST Web服务(扩展了RuntimeException
类)中发生自定义异常时,客户端无法正确捕获它,并且向我显示以下消息:
“ timestamp”:“ 2018-05-28T14:25:15.393 + 0000”,“ status”:500,
“ error”:“内部服务器错误”,“ message”:“ java.util.concurrent.ExecutionException:org.springframework.web.client.HttpServerErrorException:500 null”,
“路径”:“ /客户/结果”
有人知道我该如何解决问题? 我希望客户端向我显示自定义异常消息。
服务器代码如下:
配置类别:
@Configuration
@EnableAsync
public class ConfigurationClass {
@Bean
public Executor threadPoolTaskExecutor() {
return new ThreadPoolTaskExecutor();
}
}
控制器类:
@RestController
@RequestMapping("/server")
public class ControllerClass {
@GetMapping("/start")
@Async
public CompletableFuture<String> callService() throws InterruptedException{
Thread.sleep(10000L);
if(true)
throw new RuntimeException("Custom Error");
return CompletableFuture.completedFuture("OK");
}
}
客户端代码(消费者)如下:
@RestController
@RequestMapping("/client")
public class ControllerClass {
private ListenableFuture<ResponseEntity<String>> entity;
@GetMapping("/start")
@Async
public void callService() throws InterruptedException {
AsyncRestTemplate restTemplate = new AsyncRestTemplate();
entity = restTemplate.getForEntity("http://localhost:8080/server/start",
String.class);
}
@GetMapping("/state")
public boolean getState() {
try {
return entity.isDone();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@GetMapping("/result")
public ResponseEntity<String> getResult() {
try {
return entity.get();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
谢谢您的帮助,问候。
已添加19/05/2018 ---------------------------------------
我已经解决了。 在Web服务的控件类中,我在以下代码中添加了@ExceptionHandler
注释的方法:
@ExceptionHandler(RuntimeException.class)
void handleIllegalArgumentException(HttpServletResponse response) throws IOException {
response.sendError(200, "custom Error");
}
它工作正常,客户端已经正确识别了该异常,但是,如果我在Web服务中通过其他方式更改状态(例如201、400、401,它们是HTTP有效状态 ),则返回以获取消息"java.util.concurrent.ExecutionException: org.springframework.web.client.HttpServerErrorException: 500 null"
,在客户端中。
有人知道原因吗?
当RestTemplate
收到4xx或5xx响应代码时,它将其视为错误并抛出HttpClientErrorException
/ HttpServerErrorException
,而不是返回ResponseEntity
。
对于您的用例,您可以设置一个错误处理程序(从DefaultResponseErrorHandler
扩展),该错误处理程序不将4xx和5xx响应视为错误。
代替
AsyncRestTemplate restTemplate = new AsyncRestTemplate();
使用以下代码
AsyncRestTemplate asyncRestTemplate = new AsyncRestTemplate();
asyncRestTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
@Override
protected boolean hasError(HttpStatus statusCode) {
return false;
}
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.