如何正确处理流为空的情况

时间:2018-10-03 15:56:17

标签: spring-webflux

如何响应流为空而执行具有副作用的操作?例如,要处理客户发送空主体的情况,我们用.bodyToMono(...)来读取它。

例如参见

public Mono<ServerResponse> createEventDetails(ServerRequest request) {
    return request.principal().flatMap(principal -> {
        UserProfile userProfile = (UserProfile) ((UsernamePasswordAuthenticationToken) principal).getCredentials();

        final String id = request.pathVariable("id");
        final UUID eventId = UUID.fromString(id);

        return request.bodyToMono(CreateEventDetailsRequest.class)
            .map(body -> new CreateEventDetailsCommand(eventId, userProfile, body.getObjectId(), body.getDocumentUrls()))
            .flatMap(command -> {
                createEventDetailsCommandHandler.handle(command);
                return ServerResponse
                    .created(URI.create(eventId.toString()))
                    .body(BodyInserters.fromObject(new CreateEventDetailsResponse(eventId)));
            })
            .switchIfEmpty(ServerResponse.badRequest().syncBody(new Error("missing request body for event id: " + id)))
            .map(response -> {
                LOG.error("POST createEventDetails: missing request body for event id: " + id);
                return response;
            });
    });
}

在客户端省略请求正文的情况下,这将返回期望的400响应,但是即使成功请求,日志消息也会始终打印。

我对这种情况为什么发生的最好猜测是,.switchIfEmpty(...).map(...)由框架作为一个单元执行,然后忽略结果。

该如何处理?

1 个答案:

答案 0 :(得分:1)

有几种方法可以做到这一点。在上述情况下,您只需将日志添加到交换机 例如

.switchIfEmpty(ServerResponse.badRequest().syncBody(new Error("missing request body for event id: " + id))
       .doOnNext(errorResponse -> LOG.error("POST createEventDetails: missing request body for event id: " + id)
)

另一种方法是将错误信号发送回去,并在处理程序中捕获并记录它。 您可以在这里https://www.baeldung.com/spring-webflux-errors中查看 在这里https://docs.spring.io/spring-framework/docs/5.0.0.BUILD-SNAPSHOT/javadoc-api/org/springframework/web/server/WebHandler.html

可以找到一些浅读内容。
  

使用HttpWebHandlerAdapter使WebHandler适应HttpHandler。的   WebHttpHandlerBuilder提供了一种方便的方法,同时   (可选)配置一个或多个过滤器和/或异常处理程序。

您可以在ResponseStatusExceptionHandler

中查看示例处理程序