如何在Spring中使用CompletableFuture.exceptionaly()时更改响应statuc代码?

时间:2017-08-28 10:11:01

标签: java spring spring-mvc asynchronous spring-boot

我有一个简单的控制器:

@RestController
public class SimpleController() {

    public String get() {
        if (System.nanoTime() % 2 == 0)
            throw new IllegalArgumentException("oops");

        return "ok"
    }
}

Controller可以抛出简单的异常,所以我为它处理编写了控制器顾问:

@ExceptionHandler(IllegalArgumentException.class)
@ResponseBody
public ResponseEntity<String> rejection(Rejection ex) {
    return new ResponseEntity<>("bad", HttpStatus.CONFLICT);
}

现在我想让get方法异步。但我不知道处理异常的最佳方法。

我试过了:

    public CompletableFuture<String> get() {
        CompletableFuture.supplyAsync(
            () -> {
                if (System.nanoTime() % 2 == 0)
                    throw new IllegalArgumentException("oops");

                return "ok";
            }).exceptionally(thr -> {
                //what should i do?
                if (thr instanceof IllegalArgumentException)
                    throw ((IllegalArgumentException) t);

                if (thr.getCause() instanceof IllegalArgumentException)
                    throw ((IllegalArgumentException) t.getCause());

                return null;
            }
    }

但是控制器顾问仍然没有捕获异常。

我还试图返回ResponseEntity(&#34; message&#34;,HttpStatuc.CONFLICT);特别阻止。 但在测试中我仍然有MvcResult.getResponse()。getStatus()== 200。

还有其他想法吗? 也许这是一个错误的方式?

更新 我不知道为什么,但它没有捕获例外:

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
    return new AsyncUncaughtExceptionHandler() {
        @Override
        public void handleUncaughtException(Throwable ex, Method method, Object... params) {
            System.out.println();
        }
    };

即使它有效,如何将http状态设置为响应?

2 个答案:

答案 0 :(得分:0)

尝试返回ResponseEntity个实例:

return new ResponseEntity<>("bad", HttpStatus.CONFLICT);

exceptionally方法。

答案 1 :(得分:0)

对不起家伙,问题不在代码中。 我刚写了不好的测试。 这里有解释链接:

https://sdqali.in/blog/2015/11/24/testing-async-responses-using-mockmvc/

只需使用:

MvcResult result = mockMvc.perform(...).andReturn();
result = mockMvc.perform(asyncDispatch(result)).andReturn();

在检查状态或结果响应之前。