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

How to correctly handle the case where a stream is empty

如何执行具有副作用的操作以响应流为空?比如处理client发送空body的情况,我们用.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;
            });
    });
}

这 returns 在客户端省略请求正文的情况下所需的 400 响应,但始终打印日志消息,即使对于成功的请求也是如此。

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

我该如何处理这种情况?

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

.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

Use HttpWebHandlerAdapter to adapt a WebHandler to an HttpHandler. The WebHttpHandlerBuilder provides a convenient way to do that while also optionally configuring one or more filters and/or exception handlers.

您可以在 ResponseStatusExceptionHandler

中查看示例处理程序