我想提出一种情况,如果对象存在,则发送错误,如果不存在,则创建新用户。
这是我的处理程序:
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情况的解决方案是什么。
答案 0 :(得分:1)
最后我能够解决它,我读了两次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);
}
答案 1 :(得分:0)
您是否也可以共享您的客户代码。我假设您使用WebClient来调用此API。 客户端不应多次订阅,否则会出现此错误。