java - 如何使用 REST Web 服务和 Spring 中的 CompletableFuture 类捕获异常?
问题描述
我已经使用 spring 框架和 REST 开发了一些异步 Web 服务,我已经从使用 spring class 创建的客户端使用它AsyncRestTemplate
。类返回一个对象ListenableFuture<ResponseEntity<T>>
(使用方法getForEntity
),它带来 Web 服务返回的值(使用方法.get():<T>
)。它工作正常,但是当 REST Web 服务(扩展类)中发生自定义异常时,RuntimeException
客户端无法正确捕获它,它会向我显示以下消息:
“时间戳”:“2018-05-28T14:25:15.393+0000”,“状态”:500,
“错误”:“内部服务器错误”,“消息”:“java.util.concurrent.ExecutionException:org.springframework .web.client.HttpServerErrorException: 500 null",
"path": "/client/result"
有人知道我该如何解决这个问题吗?我希望客户端向我显示自定义异常消息。
服务器代码如下:
配置类:
@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);
}
}
}
感谢您的帮助,问候。
已于 2018 年 5 月 19 日添加---------------------------------------
我接近解决方案。在 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;
}
});
推荐阅读
- node.js - 如何将构建结果 [html 文件] 从 Jenkins 推送到 GitHub Pages?
- java - 在 websocket url 中传递凭据
- docker - 从 GitLab CI 中的服务容器访问项目目录
- amadeus - Amadeus Flight 提供不同的价格
- python-3.x - 我们应该返回然后打印结果还是只在函数内打印结果?
- node.js - 如何仅在活动 LTS 甚至当前版本上运行 azure 管道?
- javascript - 如何使不同的幻灯片在单个页面上工作?
- javascript - 如何在 ASP 样板中使用事件总线
- python-3.x - 更新和删除按钮上的 Django NoReverseMatch 错误
- python - Python打印列表中每个字符串的第n个字符?