San*_*jay 6 spring spring-data-mongodb project-reactor spring-webflux
在 Spring MVC 中,我有一个@UniqueEmail自定义的休眠验证器(用于在注册时检查电子邮件的唯一性),如下所示:
public class UniqueEmailValidator
implements ConstraintValidator<UniqueEmail, String> {
private UserRepository userRepository;
public UniqueEmailValidator(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
public boolean isValid(String email, ConstraintValidatorContext context) {
return !userRepository.findByEmail(email).isPresent();
}
}
Run Code Online (Sandbox Code Playgroud)
现在我正在使用反应式 MongoDB 迁移到 WebFlux,代码如下:
public class UniqueEmailValidator
implements ConstraintValidator<UniqueEmail, String> {
private MongoUserRepository userRepository;
public UniqueEmailValidator(MongoUserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
public boolean isValid(String email, ConstraintValidatorContext context) {
return userRepository.findByEmail(email).block() == null;
}
}
Run Code Online (Sandbox Code Playgroud)
首先,block像上面那样使用看起来不太好。其次,它不起作用,这是错误:
Caused by: java.lang.IllegalStateException: block()/blockFirst()/blockLast() are blocking, which is not supported in thread reactor-http-nio-3
Run Code Online (Sandbox Code Playgroud)
这件事该怎么办呢?我当然可以使用 MongoTemplate 阻塞方法,但是有没有办法反应性地处理这个问题?我可以在服务方法中手动执行此操作,但我希望将此错误与其他错误(例如“短”密码)一起显示给用户。
Scheduler从 Reactor 3.2.0 开始,禁止在并行或单个内部使用阻塞 API,并会引发您所看到的异常。所以,当你说它看起来不太好时,你说得对——它不仅对你的应用程序真的很糟糕(它可能会阻止新请求的处理并使整个事情崩溃),而且它太糟糕了,以至于 Reactor 团队决定将其视为错误。
现在的问题是您想在调用中执行一些与 I/O 相关的工作isValid。该方法的完整签名是:
boolean isValid(T value, ConstraintValidatorContext context)
Run Code Online (Sandbox Code Playgroud)
签名表明它是阻塞的(它不返回反应类型,也不提供结果作为回调)。所以你不能在那里做 I/O 相关的或涉及延迟的工作。在这里,您想要根据数据库检查一个条目,该条目恰好属于该类别。
我认为您不能将其作为此验证合同的一部分,而且我不知道有任何替代方案。
| 归档时间: |
|
| 查看次数: |
1676 次 |
| 最近记录: |