如何在Spring Reactor中将flatMap或flatMapMany的多个语句包含在Mono或FLux的主体中?

时间:2018-04-20 06:15:01

标签: spring project-reactor

我的代码如下:

        Mono<Property> property = propertyService.findById(id);

        String title;

        Flux<Photo> photos = property.flatMapMany(prop -> 
        {
            title = prop.title + '-' + prop.type;

          return photoService.findByPropertyId(prop.getId());
        }
        );
        model.addAttribute("prop", property);
        model.addAttribute("title", title);
        model.addAttribute("photos", photos);
        // ajx is query param coming from request
        if(ajx != null && !ajx.isEmpty() && ajx.equals("1"))
            return Mono.just("fragments/propertyfrag");
        else
        return Mono.just("property");

代码显示了我想要实现的内容,但它甚至没有编译。它给出了错误,说道具上的标题和类型不可见。

请注意,最后一个语句是对thymeleaf模板名为property的引用。在没有thyeleaf模板的情况下,我可以访问变量prop,好像它不是被动的,而是普通的prop对象,它使我能够直接访问prop对象上的参数。这是否意味着在thymeleaf模板中执行了property.block()?

在实际代码中,在上面的代码中获取title变量之后我需要做一些业务逻辑,因此我无法利用作为模型属性传递给thymleaf模板的prop直接在thymeleaf中获取标题。

如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

请记住,Flux<Photo>是一个异步过程,因此它无法以此命令式样式更新其外的title变量。请注意,您的Flux<Photo>也永远不会订阅或撰写,因此实际上永远不会被调用...

回答你的另一个问题,是的,在Spring Framework 5中,Mono传递给Thymeleaf的Map将会懒散地解决Mono并在Thymeleaf模型中注入结果值。

有关使用photos flux的更多信息,对于标题生成,您可能需要撰写更多内容:

propertyService.findById(id)
    .doOnNext(prop -> model.addAttribute("prop", prop)) //reactively add the prop to the model
    .flatMapMany(prop -> {
        String title = prop.title + '-' + prop.type;
        if(validate(title)) //do some validation
            return photoService.findByPropertyId(prop.getId());
        else
            return Mono.error(new IllegalArgumentException("validation failed"));
    }) //not sure what you do with the `Photo`s there :/
    //for now let's ignore the flux photos and at the end simply emit a String to change the view:
    .thenReturn("property"); //then(Mono.just("property")) in older versions of reactor 3.1.x