【问题标题】:spring rector throw Exception if NOT empty如果不为空,则弹簧校长抛出异常
【发布时间】:2019-12-09 10:21:51
【问题描述】:

类似于Spring Reactor: How to throw an exception when publisher emit a value?

我的 DAO java findSomePojo 中有一个查找器方法,它返回结果 SomePojo 。 finder 调用 amazon db apis,javasoftware.amazon.awssdk.services.dynamodb.model.GetItemResponse 有调用输出。 所以我在我的服务层 createSomePojo 方法中尝试这个 hasElement() 检查。 (不确定我是否正确使用它-我正在尝试和调试)

基本上: 我想检查是否已经存在元素,保存是非法的,我不会调用 DAO 保存。所以我需要抛出异常。

假设数据库中已经有 SomePojo 的记录,我尝试调用 service 的 create_SomePjo 。但是我在日志中看到过滤器不起作用并且当反应器调用 createModel_SomePojo 时得到 NPE 让我相信,即使在检查过滤器之后它抛出 NPE

///service SomePjoService it has create_SomePojo, find_SomePojo etc

Mono<Void>  create_SomePojo(reqPojo){

// Before calling DAO 's save I call serivice find (which basically calls DAOs find (Shown befow after this methid)
       Mono<Boolean> monoPresent = find_SomePojo(accountId, contentIdExtn)
                 .filter(i -> i.getId() != null)
                 .hasElement();
       System.out.println("monoPresent="+monoPresent.toString());
       if(monoPresent.toString().equals("MonoHasElement")){
       //*************it comes here i see that***********//
           System.out.println("hrereee monoPresent="+monoPresent);
          // Mono<Error> monoCheck=
                return  monoPresent.handle((next, sink) -> sink.error(new SomeException(ITEM_ALREADY_EXISTS))).then();
       } else {
           return SomePojoRepo.save(reqPojo).then();
       }

}

Mono<SomePojo> find_SomePojo(id){
    return SomePojoRepo.find(id);
}

==============================================================

///DAO : SomePojoRepo.java : it has save,find,delete
Mono<SomePojo> find( String id) {
    Mono<SomePojo> fallback = Mono.empty();
    Mono<GetItemResponse> monoFilteredResponse = monoFuture
        .filter(getItemResponse -> getItemResponse.item().size() > 0&& getItemResponse!=null);
    Mono<SomePojo> result = monoFilteredResponse
        .map(getItemResponse -> createModel_SomePojo(getItemResponse.item()));

    Mono<SomePojo> deferedResult = Mono.defer(() -> result.switchIfEmpty(fallback));
        return deferedResult;
}

我看到 Mono 上有 hasElement() 方法。不知道如何正确使用它。 如果我直接在我的服务 create_SomePojo(reqPojo) 中调用 DAO save 而不做所有这些查找器检查,我可以实现异常,因为主键约束会小心并抛出异常,我 cna 重新抛出然后在服务中捕获但是如果我想签入服务并抛出带有错误代码的异常。这个想法不是将响应错误对象传递给 dao 层。

【问题讨论】:

  • 您确定问题与过滤器 lambda 表达式中的条件无关吗?从左到右计算表达式。恕我直言,您应该首先检查 getItemResponse != null
  • 添加了一些细节
  • 改变过滤条件为:getItemResponse -> getItemResponse!=null && getItemResponse.item().size() > 0
  • OK 。这修复了过滤条件。但不知何故 hasElement() 现在不起作用。我认为它正在工作,但现在即使对于新请求,它也会首先进入 if 条件而不是直接保存。所以现在我总是看到我的自定义异常:)。猜猜我没有正确使用 hasElement 或者什么是处理的正确方法..?
  • create_SomePojo() 和 createModel_SomePojo() 在这段代码中是一样的吗?

标签: spring-boot project-reactor reactive


【解决方案1】:

尝试使用Hooks.onOperatorDebug()钩子以获得更好的调试体验。

使用hasElement的正确方法(假设find_SomePojo永远不会返回null)

Mono<Boolean> monoPresent =  find_SomePojo(accountId, contentIdExtn)
        .filter(i -> i.getId() != null)
        .hasElement();

return monoPresent.flatMap(isPresent -> {
    if(isPresent){
        Mono.error(new SomeException(ITEM_ALREADY_EXISTS)));
    }else{
        SomePojoRepo.save(reqPojo);
    }
}).then();

旁注

对于Mono 的实际含义存在一个普遍的误解。它不保存任何数据——它只是一个管道片段,用于传输流经它的信号和数据。因此,System.out.println("monoPresent="+monoPresent.toString()); 行没有任何意义,因为它只是在现有管道周围打印hasElements() 装饰器。这个装饰器的内部名称是MonoHasElement,不管它包含什么(true /false),MonoHasElement 无论如何都会被打印出来。

打印信号(以及随之传输的数据)的正确方法是: Mono.log()Mono.doOnEach/next(System.out::println)System.out.println("monoPresent="+monoPresent.block());。注意第三个:它会阻塞整个线程,直到发出数据,所以只有在你知道自己在做什么的情况下才使用它。

使用 Monos 打印的示例:

   Mono<String> abc = Mono.just("abc").delayElement(Duration.ofSeconds(99999999));

    System.out.println(abc); //this will print MonoDelayElement instantly
    System.out.println(abc.block()); //this will print 'abc', if you are patient enough ;^)
    abc.subscribe(System.out::println); //this will also print 'abc' after 99999999 seconds, but without blocking current thread

【讨论】:

  • 是的,我的队友也提出了同样的建议。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-12
  • 1970-01-01
相关资源
最近更新 更多