1

我想提出一个案例,如果对象存在则发送错误,如果不存在则创建新用户。

这是我的处理程序:

public Mono<ServerResponse> createUser(ServerRequest request) {
        Mono<UserBO> userBOMono = request.bodyToMono(UserBO.class);
        Mono<String> email = userBOMono.map(UserBO::getEmail);
        Mono<User> userMono = email.flatMap(userRepository::findByEmail);
        return userMono.flatMap(user -> {
            Mono<ErrorResponse> errorResponseMono = errorHanlder.handleEmailAlreadyExist();
            return ServerResponse.status(HttpStatus.CONFLICT)
                    .contentType(MediaType.APPLICATION_JSON)
                    .body(errorResponseMono, ErrorResponse.class);
        }).switchIfEmpty(Mono.defer(() -> {
            Mono<User> newUserMono = userBOMono.flatMap(userMapping::mapUserBOToUser);
            Mono<User> dbUserMono = newUserMono.flatMap(userRepository::save);
            return ServerResponse.status(HttpStatus.CREATED)
                    .contentType(MediaType.APPLICATION_JSON)
                    .body(dbUserMono, User.class);

        }));

如果 Mono 不为空,那么它的返回冲突就是我想要的如果如果为空则创建新的但它抛出以下错误:

java.lang.IllegalStateException: Only one connection receive subscriber allowed.
    at reactor.ipc.netty.channel.FluxReceive.startReceiver(FluxReceive.java:276) ~[reactor-netty-0.7.8.RELEASE.jar:0.7.8.RELEASE]
    at reactor.ipc.netty.channel.FluxReceive.lambda$subscribe$2(FluxReceive.java:127) ~[reactor-netty-0.7.8.RELEASE.jar:0.7.8.RELEASE]
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute$$$capture(AbstractEventExecutor.java:163) ~[netty-common-4.1.27.Final.jar:4.1.27.Final]
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java) ~[netty-common-4.1.27.Final.jar:4.1.27.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404) ~[netty-common-4.1.27.Final.jar:4.1.27.Final]
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:464) ~[netty-transport-4.1.27.Final.jar:4.1.27.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884) ~[netty-common-4.1.27.Final.jar:4.1.27.Final]
    at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_131]

更新说明:根据方法定义其正确行为:

switchIfEmpty(Mono<? extends T> alternate)
Fallback to an alternative Mono if this mono is completed without data

意味着当我在正文中发送空的 Mono 时,它的工作正常:

return ServerResponse.status(HttpStatus.CREATED)
                    .contentType(MediaType.APPLICATION_JSON)
                    .body(Mono.empty(), User.class);

那么如果我想发送 Mono 对象作为返回,那么处理 swtichIfEmpty 情况的解决方案是什么。

4

2 回答 2

2

最后我能够解决它,我正在读取 userBOMono 流两次,这导致 webflux 抛出此错误。

所以这里是更新的代码,它工作正常。

 public Mono<ServerResponse> createUser(ServerRequest request) {
        Mono<UserBO> userBOMono = request.bodyToMono(UserBO.class);
        return userBOMono.flatMap(userBO -> {
            String email = userBO.getEmail();
            Mono<User> userMono = userRepository.findByEmail(email);
            return userMono.flatMap(user -> errorHandler.handleEmailAlreadyExist())
                    .switchIfEmpty(Mono.defer(() -> createNewUser(userBO)));
        });
    }

    private Mono<ServerResponse> createNewUser(UserBO userBO) {
        Mono<User> userMono = Mono.just(userBO).flatMap(userMapping::mapUserBOToUser).flatMap(userRepository::save);
        return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)
                .body(userMono, User.class);

    }
于 2018-09-12T07:36:38.557 回答
0

我假设您使用 WebClient 来调用此 API。客户端不应订阅多次,否则会出现此错误。

于 2018-09-09T07:53:08.257 回答