如何在 Spring WebFlux @ExceptionHandler 中访问 RequestBody?

pet*_*erl 5 java spring spring-boot spring-webflux

有没有办法使用默认的 Reactor NettyRequestBody@ExceptionHandler使用 Spring WebFlux的方法中访问(最好以它的映射形式)?

考虑以下示例:

@RestController
class TestRestController {

  @PostMapping("/test")
  Mono<TestBody> testPost(@RequestBody TestBody testBody) {
    return Mono.error(new NullPointerException());
  }

  @ExceptionHandler(NullPointerException.class)
  @ResponseStatus(HttpStatus.BAD_REQUEST)
  Mono<Void> handleNullPointerException(ServerWebExchange serverWebExchange) {
    return Mono.empty();
  }

}
Run Code Online (Sandbox Code Playgroud)

在运行时,可以将某些类型的其他实例注入到@ExceptionHandler的方法签名中,如上面带有ServerWebExchange. 但是文档明确指出它不支持请求正文参数(请参阅本节中的注释)。

使用 Servlet 堆栈,您可以RequestContext此处所示注入。WebFlux 堆栈是否有等效或类似的方法?

bre*_*Dev 0

是的,有一种方法,但不是一种很好看的方法。我们遇到了同样的问题,但在我们的例子中,我们希望能够访问反应式上下文,因为我们顽固地选择在这种反应式范例中使用 MDC,因此 MDC 依赖于该上下文。

经过多次反复讨论异常处理程序和控制器建议后,很明显无法在那里访问反应式上下文。

所以我们扩展了AbstractErrorWebExceptionHandler。这里有一个handle(ServerWebExchange Exchange, Throwable throwable)方法,当应用程序出现错误时将调用该方法。好的部分是,有 ServerWebExchange 您可以访问上下文,例如:exchange.getAttributes().get(MDC_CONTEXT)或正文,例如:exchange.getRequest().getBody()

这样就解决了我们的 MDC 问题,但不幸的是,错误的映射必须手动处理。我记得我们投入了很多时间,当时这是最好的解决方案。干杯!