【问题标题】:How to change response statuc code when using CompletableFuture.exceptionaly() in Spring?在 Spring 中使用 CompletableFuture.exceptionally() 时如何更改响应状态码?
【发布时间】:2018-02-05 13:57:53
【问题描述】:

我有一个简单的控制器:

@RestController
public class SimpleController() {

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

        return "ok"
    }
}

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

@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("message", 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状态响应?

【问题讨论】:

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


【解决方案1】:

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

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

只需使用:

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

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

【讨论】:

    【解决方案2】:

    尝试返回一个ResponseEntity 实例:

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

    超出exceptionally 方法。

    【讨论】:

    • 我应该在哪里退货?
    • 异常(thr -> new ResponseEntity("bad", HttpStatus.CONFLICT));
    猜你喜欢
    • 1970-01-01
    • 2021-12-14
    • 2019-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-24
    • 2017-05-24
    相关资源
    最近更新 更多