我想从Flux / Mono获取对象。 我用
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
我这样做:
Mono<UserEntity> byEmail = userRepository.findByEmail(userDto.getEmail());
UserEntity block = byEmail.block();
我有错误:
java.lang.IllegalStateException: block()/blockFirst()/blockLast() are blocking, which is not supported in thread reactor-http-nio-3
为什么?有什么不同的方法获取对象?
在反应式编程中如何执行以下操作: 在RequestBody中,您具有UserDto。
如果没有创建用户,请检查数据库中是否存在电子邮件。
return userRepository.findByEmail(userDto.getEmail())
//rethrow DB errors as BadRequestException, except user exists
.onErrorResume(t -> Mono.error(new BadRequestException()))
//throwing in map is converted to onError signal
.map(ifItGoesThereItExist-> { throw new UserByEmailExistException(); })
//switchIfEmpty to replace an empty source with a different Mono
.switchIfEmpty(createUser(userDto))
//at this point, map can only receive an onNext from the createUser
.map(u -> new ResponseEntity(u, HttpStatus.CREATED))
;
答案 0 :(得分:0)
您似乎找到了答案,但是让我详细说明一下。
为什么您不能阻止
您收到的错误消息表示您尝试恢复为不适合阻塞的特定Thread
(或线程池)内部的阻塞行为。这是Spring Webflux(在Netty的掩护下)用来处理应用程序中每个传入请求的线程。因此,如果阻止它,则将根本阻止应用程序处理新请求。
您的答案和一些小改进
首先,map
可以简化,因为null
或Flux
中不允许使用Mono
值。如果该值不在数据库中,则Spring数据ReactiveCrudRepository
将返回一个空的Mono
,不要与发出Mono
的{{1}}混淆:
null
vs
---( null )---|->
onNext(null), onComplete() // onNext(null) being forbidden
我还认为,对于---|->
onComplete()
,您打算包装DB错误,但“用户存在”情况除外?如果是这样,则此onErrorResume
的放置是错误的,因为它类似于也会捕获onErrorResume
的{{1}}。将其放在catch(Throwable e)
之前 。您也可以直接从地图内投掷。
因此,这归结为检测空UserByEmailExistException
与值map
,用异步数据库保存替换空的Mono
,而用Mono
替换空的值:
TL; DR给我代码了
onError