当前位置: 首页 > 知识库问答 >
问题:

WebFlux添加阻塞逻辑

邵轶
2023-03-14

我想知道如何在创建新对象之前进行一些验证检查?

@Override
public Mono<Child> create(CreateChildRequest specs) {

    final String parentId = specs.getParentId();
    // TODO: Check if parent exists
    // parentRepository.getById(parentId) -> returns Mono<Parent>

    final Child newChild = new Child(specs.getParentId(), specs.getName());
    return childRepository.insert(newChild)
            .switchIfEmpty(Mono.error(new ResponseStatusException(HttpStatus.BAD_REQUEST, "Failed to create child")));
}

如何以非阻塞方式添加验证检查?

共有2个答案

尉迟明贤
2023-03-14

也许像这样的东西,没有运行代码,但你知道了它的要点。

@Override
public Mono<Child> create(CreateChildRequest specs) {

    final String parentId = specs.getParentId();
    return parentRepository.getById(parentId)
        .doOnSuccess(parent -> {
            verify(parent).doOnSuccess(() -> {
                childRepository.insert(newChild).doOnError(throwable -> {
                    throw new ResponseStatusException(
                        HttpStatus.BAD_REQUEST,
                        "Failed to create child")
                }).doOnError(throwable -> {
                    // some error handling here if not passing validation.
                })
            })
        })
}

private Mono<Void> verify(Parent parent) {

    if(parent == null)
        return Mono.error(// some error here);
    else
        Mono.empty();
}
杜昆琦
2023-03-14

如果只需要执行简单的非阻塞检查,即检查某些字段(或通常不需要播放另一个单声道),可以在doOnNext操作符中执行,并轻松提取到其他方法。此块中引发的任何异常都将转换为Mono。错误

final String parentId = specs.getParentId();

    parentRepository.getById(parentId)
        .switchIfEmpty(Mono.error(new ResponseStatusException(HttpStatus.BAD_REQUEST, "Parent does not exist")))
        .doOnNext(parent -> {
            if (parent.getSomeField() == null) { //this can be easily extracted for readability
                throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Some field must not be null");
            }
        })
        .then(Mono.just(new Child(specs.getParentId(), specs.getName()))
                .flatMap(childRepository::insert)
                .switchIfEmpty(Mono.error(new ResponseStatusException(HttpStatus.BAD_REQUEST, "Failed to create child")));

如果执行检查需要涉及另一个流量(例如调用另一个webservice),则需要使用“订阅”操作符,如flatMap或zip。

    @Override
    public Mono<Child> create(CreateChildRequest specs) {
        final String parentId = specs.getParentId();

        parentRepository.getById(parentId)
            .switchIfEmpty(Mono.error(new ResponseStatusException(HttpStatus.BAD_REQUEST, "Parent does not exist")))
            .flatMap(parent -> validate(parent))
            .then(Mono.just(new Child(specs.getParentId(), specs.getName()))
                    .flatMap(childRepository::insert)
                    .switchIfEmpty(Mono.error(new ResponseStatusException(HttpStatus.BAD_REQUEST, "Failed to create child")));
                }

            }

Mono<Void> validate(Parent parent){
    //some non blocking io logic ending with Mono.empty or Mono.error
}
 类似资料:
  • 这是一个非阻塞的解决方案,但看起来并不那么优雅。它能以某种方式改进/简化吗?

  • 我决定在Java上重写我的Web应用程序(以前是在Python上)。在我的应用程序中,我使用无阻塞I/O,我有工作池(Celery Eventlet线程),我在其中传递由数百个API调用组成的任务。 现在我正在使用Spring WebFlux,但我不明白如何创建一个工作人员池来将我的任务传递到该池,并在获得结果并进行一些计算之后。 (我知道创建ThreadPoolTaskExecutor的可能性,

  • 我正在使用Spring Webflux和Spring Boot2,我的场景如下: 在返回之前,我如何将来自流量和正常产品列表的结果连接起来?没有反应控制器是可能的吗? 附言。我不想对从调用1获得的结果调用。block()和CompleteableFuture

  • 我正在使用Spring Webflux和Spring Data MongoDB Reactive。在我的REST控制器中,我试图从数据库(MongoDB)中获取一种类型的所有对象(例如,一个品牌的所有自行车)。我当前的实现看起来是这样的: 为了保持反应模式,我希望避免block()调用。我尝试了map()和doOnSuccess()的多种组合,但没有找到正确的方法来完成我想要做的事情。我在网上找到

  • 我正在使用静态编程语言和Arrow以及来自的WebClient。我想做的是将Mono实例转换为要么。 通过调用

  • 问题内容: 我有这段代码可以在Linux中从Serial读取,但是我不知道在读取SerialPort时阻塞和非阻塞之间有什么区别,在哪种情况下哪个更好? 问题答案: 您提到的代码是IMO编码和注释不当的代码。该代码不符合POSIX的可移植性惯例,如正确设置终端模式和POSIX操作系统的串行编程指南中所述。该代码没有提到它使用非规范(也称为原始)模式,并且重用了“阻塞”和“非阻塞”术语来描述 VMI