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

如何仅在Mono为空时执行操作,如果不为空则抛出错误

戎桐
2023-03-14

我正在尝试将一个项目转换为使用SpringWebFlux,但遇到了一个问题:如何让一些基本的业务逻辑正常工作。我有一个存储库层负责检索/持久化记录,还有一个服务层负责应用程序的业务规则。我想做的(在服务层)是检查给定用户名的用户是否已经存在。如果是这样,我想用一个错误来回应。如果没有,我希望允许插入发生。

我在存储库层调用一个方法,该方法将通过用户名查找用户,如果找不到,它将返回一个空的Mono。这是预期的工作;但是,我尝试了flatMap和(defaultIfEmpty和swithIfEmpty)的各种组合,但无法将其编译/构建。

    public Mono<User> insertUser(User user) {
        return userRepository.findByUsername(user.username())
            .flatMap(__ -> Mono.error(new DuplicateResourceException("User already exists with username [" + user.username() + "]")))
            .switchIfEmpty(userRepository.insertUser(user));
    }

我得到的错误是Mono


共有3个答案

唐海阳
2023-03-14

我使用的抽象类具有类型参数E,因此无法使用。铸造(E.class)。我们的解决办法是

private Mono<E> checkIfStatementExists(E statement) {
    return this.statementService.getByStatementRequestId(statement.getStatementRequestId())
            .flatMap(sr -> Mono.<E>error(new ValidationException("Statement already exists for this request!")))
            .switchIfEmpty(Mono.just(statement));
}

我想我下周需要和同事讨论这件事。

编辑。我们与同事进行了讨论,更新的代码在上面。

柳奇思
2023-03-14

出现此编译器错误的原因如下。

获取已完成的Mono中的内容,并尝试将其转换为它可以推断的任何类型。Mono.error包含一个类型,该类型属于Object。

一种方法可以是将逻辑移动到平面图中。

// This is just example code using strings instead of repos
public Mono<String> insertUser(String user) {
    return Mono.just(user)
            // Here we map/convert instead based on logic
            .flatMap(__ -> {
                if (__.isEmpty())
                    return Mono.error(new IllegalArgumentException("User already exists with username [" + user + "]"));
                return Mono.just(user);
            }).switchIfEmpty(Mono.just(user));
}

\fs16\an2\b0\b0\b0\b0\b0\b0\b0\b0对于做出逻辑决策来说不是超级好。留档上写着

如果这个单声道在没有数据的情况下完成,回退到另一个单声道

如果我们没有得到任何东西,这更像是一种退回到其他地方的退路,所以我们可以继续数据流。

你也可以

Mono.empty().doOnNext(o -> {
        throw new IllegalArgumentException("User already exists with username [" + o + "]");
    }).switchIfEmpty(Mono.just("hello")).subscribe(System.out::println);
崔单弓
2023-03-14

经过额外的测试,并考虑到其他开发人员的响应,我找到了以下解决方案:

    public Mono<User> insertUser(User user) {
        return userRepository.findByUsername(user.username())
            .flatMap(__ -> Mono.error(new DuplicateResourceException("User already exists with username [" + user.username() + "]")))
            .switchIfEmpty(Mono.defer(() -> userRepository.insertUser(user)))
            .cast(User.class);
    }

正如托马斯所说,编译器正在变得混乱。我的假设是因为flatMap返回一个带有错误的Mono,而switchIfEmpty返回一个带有用户的Mono,因此它会返回一个带有对象的Mono(因此需要额外的.cast操作符来编译它)。

另一个添加是添加Mono。延迟开关映射中的。否则,开关ifempty总是启动。

我仍然愿意接受其他建议/替代方案(因为这似乎是一个相当普遍的需求/模式)。

 类似资料:
  • 问题内容: 有没有一种方法可以在计数条件下进行插入,例如: 基本上,如果表当前为空,我想插入一个默认记录。我正在使用mysql。 问题答案: 使用SELECT而不是VALUES可以通过WHERE子句扩展查询。 EXISTS是比COUNT个更好更快的测试

  • 如果值为空,则需要在单元格中显示一个不间断的空格。这是我的模板: 我试过这个,但不管用: 它返回值的问题是: 如果许可证号带有值,则单元格为空,行颜色如下所示。 利用卢库马的建议,它表明了这一点: 更改筛选器中的if语句后,仍然不显示非值:

  • 以下是我如何发送: 或者像这样(两者都试过): 在接收端,如果我访问$\u POST,则它是空的。如果我访问文件\u获取\u内容('php://input“),然后它包含我的json。 这是怎么回事?

  • 我得到一个奇怪的错误: blank=true,null=true)文件“/mypath/lib/python2.7/site-packages/django/forms/fields.py”,第214行,在init super(CharField,self)中。init(*args,**kwargs)类型错误:init()获得意外的关键字参数“null” 在没有收到此错误的情况下,如何使此字段不是

  • 我刚刚把我的超文本标记语言转换成WordPress。你可以在这里看到。我选择了每页显示一篇文章。 但是,我注意到我没有'Previous'链接和div。我现在只有'Next'链接和div。 如果我添加了'Previous'链接和div,我如何在我的主页中隐藏它(这里有最新的条目)?我如何在最后一个条目中隐藏“下一个”链接和div,而在最后一个条目页面中只显示“上一个”链接和div? 我想这个主题更

  • 假设我的中有多个过滤器,如下所示: 现在,如果我最初没有,那么我会收到这样的消息。但如果我按某个没有结果的东西过滤,它就不会显示我理解的信息。 我的问题是,当收集或筛选没有结果时,如何实现多重筛选,并显示消息? 我把这个例子弄得一团糟。我的尝试: