Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring Webflux控制器';返回对象而不是Mono';_Spring_Mono_Spring Webflux_Spring Reactor - Fatal编程技术网

Spring Webflux控制器';返回对象而不是Mono';

Spring Webflux控制器';返回对象而不是Mono';,spring,mono,spring-webflux,spring-reactor,Spring,Mono,Spring Webflux,Spring Reactor,您好,我是Webflux的新手,我学习了构建反应式微服务的教程。在我的项目中,我面临以下问题 我想为产品服务创建一个CRUDAPI,下面是创建方法 @Override public Product createProduct(Product product) { Optional<ProductEntity> productEntity = Optional.ofNullable(repository.findByProductId(product.getProductId

您好,我是Webflux的新手,我学习了构建反应式微服务的教程。在我的项目中,我面临以下问题

我想为产品服务创建一个CRUDAPI,下面是创建方法

@Override
public Product createProduct(Product product) {

    Optional<ProductEntity> productEntity = Optional.ofNullable(repository.findByProductId(product.getProductId()).block());
             productEntity.ifPresent((prod -> {
                  throw new InvalidInputException("Duplicate key, Product Id: " + product.getProductId());
              }));

    ProductEntity entity = mapper.apiToEntity(product);
    Mono<Product> newProduct = repository.save(entity)
        .log()
        .map(mapper::entityToApi);

    return newProduct.block();
}
@覆盖
公共产品createProduct(产品产品){
Optional productEntity=Optional.ofNullable(repository.findByProductId(product.getProductId()).block());
productEntity.ifPresent((产品->{
抛出新的InvalidInputException(“重复键,产品Id:+Product.getProductId());
}));
ProductEntity=mapper.apiToEntity(产品);
Mono newProduct=repository.save(实体)
.log()
.map(映射器::entityToApi);
返回newProduct.block();
}
问题是,当我从postman调用这个方法时,我得到了错误 “block()/blockFirst()/blockLast()正在阻塞,这在thread reactor-http-nio-3中不受支持”但当我使用StreamListener时,此调用正常工作。流侦听器从rabbit mq通道获取事件

StreamListener

@EnableBinding(Sink.class)
public class MessageProcessor {

    private final ProductService productService;

    public MessageProcessor(ProductService productService) {
        this.productService = productService;
    }

    @StreamListener(target = Sink.INPUT)
    public void process(Event<Integer, Product> event) {

       
        switch (event.getEventType()) {

            case CREATE:
                Product product = event.getData();
                LOG.info("Create product with ID: {}", product.getProductId());
                productService.createProduct(product);
                break;

   
            default:
                String errorMessage = "Incorrect event type: " + event.getEventType() + ", expected a CREATE or DELETE event";
                LOG.warn(errorMessage);
                throw new EventProcessingException(errorMessage);
        }
    }
}
@EnableBinding(Sink.class)
公共类消息处理器{
私人最终产品服务;
公共消息处理器(ProductService ProductService){
this.productService=productService;
}
@StreamListener(目标=Sink.INPUT)
公共作废流程(事件){
开关(event.getEventType()){
案例创建:
Product=event.getData();
info(“创建ID为{}的产品”,product.getProductId());
productService.createProduct(产品);
打破
违约:
String errorMessage=“不正确的事件类型:“+event.getEventType()+”,应为创建或删除事件”;
日志警告(错误消息);
抛出新的EventProcessingException(errorMessage);
}
}
}
我有两个问题

  • 为什么这适用于StreamListener而不是简单的请求
  • webflux中有没有合适的方法返回Mono的对象,或者我们总是要返回Mono

  • 您的create方法希望看起来更像这样,您希望从控制器返回一个
    Mono
    ,而不仅仅是对象

      public Mono<Product> createProduct(Product product) {
        return repository.findByProductId(product.getProductId())
            .switchIfEmpty(Mono.just(mapper.apiToEntity(product)))
            .flatMap(repository::save)
            .map(mapper::entityToApi);
      }
    
    公共产品(产品){
    返回repository.findByProductId(product.getProductId())
    .switchIfEmpty(Mono.just(mapper.apiToEntity(product)))
    .flatMap(存储库::保存)
    .map(映射器::entityToApi);
    }
    
    正如@Thomas评论的那样,您正在打破反应式编码的一些基本原理,而不是通过使用block()获得好处,应该进一步阅读。例如,您正在使用的反应式mongo存储库将返回一个Mono,如果它是空的,则它有自己的处理方法,而不需要使用如上所示的可选方法

    编辑以映射到错误(如果实体已存在),否则保存

      public Mono<Product> createProduct(Product product) {
        return repository.findByProductId(product.getProductId())
            .hasElement()
            .filter(exists -> exists)
            .flatMap(exists -> Mono.error(new Exception("my exception")))
            .then(Mono.just(mapper.apiToEntity(product)))
            .flatMap(repository::save)
            .map(mapper::entityToApi);
      }
    
    公共产品(产品){
    返回repository.findByProductId(product.getProductId())
    .hasElement()
    .filter(存在->存在)
    .flatMap(存在->Mono.error(新异常(“我的异常”))
    .then(Mono.just(mapper.apiToEntity(product)))
    .flatMap(存储库::保存)
    .map(映射器::entityToApi);
    }
    
    您的创建方法希望看起来更像这样,您希望从控制器返回一个
    Mono
    ,而不仅仅是对象

      public Mono<Product> createProduct(Product product) {
        return repository.findByProductId(product.getProductId())
            .switchIfEmpty(Mono.just(mapper.apiToEntity(product)))
            .flatMap(repository::save)
            .map(mapper::entityToApi);
      }
    
    公共产品(产品){
    返回repository.findByProductId(product.getProductId())
    .switchIfEmpty(Mono.just(mapper.apiToEntity(product)))
    .flatMap(存储库::保存)
    .map(映射器::entityToApi);
    }
    
    正如@Thomas评论的那样,您正在打破反应式编码的一些基本原理,而不是通过使用block()获得好处,应该进一步阅读。例如,您正在使用的反应式mongo存储库将返回一个Mono,如果它是空的,则它有自己的处理方法,而不需要使用如上所示的可选方法

    编辑以映射到错误(如果实体已存在),否则保存

      public Mono<Product> createProduct(Product product) {
        return repository.findByProductId(product.getProductId())
            .hasElement()
            .filter(exists -> exists)
            .flatMap(exists -> Mono.error(new Exception("my exception")))
            .then(Mono.just(mapper.apiToEntity(product)))
            .flatMap(repository::save)
            .map(mapper::entityToApi);
      }
    
    公共产品(产品){
    返回repository.findByProductId(product.getProductId())
    .hasElement()
    .filter(存在->存在)
    .flatMap(存在->Mono.error(新异常(“我的异常”))
    .then(Mono.just(mapper.apiToEntity(product)))
    .flatMap(存储库::保存)
    .map(映射器::entityToApi);
    }
    
    这是一个非常基本的问题,我建议您阅读反应式编程的基础知识,Mono实际上是什么,以及为什么在反应式应用程序中不允许阻塞。反应器入门文档是一个很好的起点。从这里开始这是一个非常基本的问题,我建议您阅读反应式编程的基础知识,Mono实际上是什么,以及为什么在反应式应用程序中不允许阻塞。反应堆启动文档是一个很好的开始。从这里开始Thanx我将遵循反应堆启动文档,但正如我在您的回复中看到的,当用户已经存在时,不会抛出错误。。。如果不是空的,有没有方法抛出错误?您不会抛出传统意义上的错误,请参阅编辑到answerThanx我将遵循反应堆文档的入门指南,但正如我在您的回复中看到的,当用户已经存在时,不会抛出错误。。。如果不是空的,是否有方法抛出错误?您不会抛出传统意义上的错误,请参阅编辑以回答