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

WebFlux:为什么我需要在CRUD中使用flatMap

安博文
2023-03-14

我在互联网上找到了例子,但这并没有给我充分的理解。使用WebFlux时的标准CRUD。

路由器:

@Configuration
public class PersonRouter {

    @Bean
    public RouterFunction<ServerResponse> route(PersonHandler handler) {
        return RouterFunctions
                .route(GET("/getAllPersons").and(accept(MediaType.APPLICATION_JSON)), handler::findAll)
                .andRoute(GET("/getPerson/{id}").and(accept(MediaType.APPLICATION_STREAM_JSON)), handler::findById)
                .andRoute(POST("/createPerson").and(accept(MediaType.APPLICATION_JSON)), handler::save)
                .andRoute(DELETE("/deletePerson/{id}").and(accept(MediaType.APPLICATION_JSON)), handler::delete);
    }

}

处理程序:

@Component
public class PersonHandler {

    private final PersonService personService;

    public PersonHandler(PersonService personService) {
        this.personService = personService;
    }

    public Mono<ServerResponse> findById(ServerRequest request) {
        String id = request.pathVariable("id");
        return ok()
                .contentType(MediaType.APPLICATION_JSON)
                .body(personService.getById(id), Person.class);
    }

    public Mono<ServerResponse> findAll(ServerRequest request) {
        return ok()
                .contentType(MediaType.APPLICATION_JSON)
                .body(personService.getAll(), Person.class);
    }

    public Mono<ServerResponse> save(ServerRequest request) {
        final Mono<Person> person = request.bodyToMono(Person.class);
        return ok()
                .contentType(MediaType.APPLICATION_JSON)
                .body(fromPublisher(person.flatMap(personService::save), Person.class));
    }

    public Mono<ServerResponse> delete(ServerRequest request) {
        String id = request.pathVariable("id");
        return ok()
                .contentType(MediaType.APPLICATION_JSON)
                .body(personService.delete(id), Void.class);
    }

}
@Repository
public interface PersonRepository extends ReactiveMongoRepository<Person, String> {
}
@Service
@Transactional
@AllArgsConstructor
public class PersonService {

    private final PersonRepository personRepository;

    public Flux<Person> getAll() {
        return personRepository.findAll().switchIfEmpty(Flux.empty());
    }

    public Mono<Person> getById(final String id) {
        return personRepository.findById(id);
    }

    public Mono update(final String id, final Person person) {
        return personRepository.save(person);
    }

    public Mono save(final Person person) {
        return personRepository.save(person);
    }

    public Mono delete(final String id) {
        final Mono<Person> dbPerson = getById(id);
        if (Objects.isNull(dbPerson)) {
            return Mono.empty();
        }
        return getById(id).switchIfEmpty(Mono.empty()).filter(Objects::nonNull).flatMap(personToBeDeleted -> personRepository
                .delete(personToBeDeleted).then(Mono.just(personToBeDeleted)));
    }
}
public Mono<ServerResponse> save(ServerRequest request) {
        final Mono<Person> person = request.bodyToMono(Person.class);
        return ok()
                .contentType(MediaType.APPLICATION_JSON)
                .body(fromPublisher(person.flatMap(personService::save), Person.class));
    }
final Mono<Person> person = request.bodyToMono(Person.class);
personService::save

我是对的还是这个说法错了?

共有1个答案

裘光启
2023-03-14

为什么你需要平面地图。

这些是我的想法,答案不同取决于你是在单声道还是通量上工作。

1.

public Mono<ServerResponse> influCRUD(ServerRequest req) {
    return req.bodyToMono(S.class) // the pipline begins with S class.
       .map(s -> {s.setF1(f1); s.setF2(f2); return s;}) // the pipeline has the same intput and output, i.e. object s, you use map.
       .flatMap(s -> webClient // the pipeline has S input, and T output, you use flatMap
            .post()
            .uri(uri)
            .body(BodyInserters.fromObject(s))
            .retrive()
            .bodyToMono(T.class) 
        ).flatMap(t -> ServerResponse // now the pipeline changes again, you use flatMap.
           .ok()
           .contentType()
           .body(BodyInserters.fromObject(t))
        );
}

mono flatMap(函数<?super T,?扩展mono<?扩展r>>转换器)

函数只执行a->b,当b是另一个producer/subsciber的输出时(当您使用反应式编程时,这种情况很可能发生),如前一个示例中的WebClient部分,它是Mono或flux形式。通过使用flatMap,它为您返回mono ,其中map返回mono ,正如它们在函数声明中所述。

 类似资料:
  • 问题内容: 我开始使用RxJS,但我不明白为什么在此示例中我们需要使用类似or 的函数;数组的数组在哪里? 如果有人可以直观地解释正在发生的事情,那将非常有帮助。 问题答案: 当您有一个Observable的结果是更多Observable时,可以使用flatMap。 如果您有一个由另一个可观察对象产生的可观察对象,则您不能直接过滤,缩小或映射它,因为您有一个可观察对象而不是数据。如果您生成一个可观

  • 问题内容: 基数实际上是什么意思?我们为什么需要它? 问题答案: 您可能并不总是希望将整数解析为以10为底的数字,因此提供基数可以指定其他数字系统。 基数是一位数字的值数。十六进制为16。八进制为8,二进制为2,依此类推… 在该函数中,您可以执行一些操作来提示基数而不提供基数。如果用户输入的字符串与其中一个规则匹配,但没有明确规定,则这些方法也可能对您不利。例如:

  • 问题内容: 好的,假设我们有两个表,和。在评论中,我们有一列,它表示哪个用户键入了该特定评论。为什么我们需要将其指定为外键?如果我们不这样做,它将仍然有效。我们指定主键,因为据我所知,它可以使查询速度更快(我们只需要搜索一行,而当我们没有主键/索引时,则必须遍历所有行)。这只是一种良好的编码习惯吗? 问题答案: 使用外键时,您将获得: 数据的完整性 更快的查询。 用户: 用户ID: 1个 2个 3

  • 但代码不起作用。我是否需要将launchActivity定义为一个规则,或者是否存在我需要在Gradle中导入的库? 这些是我已经有的进口品

  • 问题内容: 我将稍微解释一下我的脚本,以便您可以理解我的问题。 基本上我做了一个脚本来检查SOCKS5是还是。 当我在上面测试我的脚本时,它运行良好,但是当我在Windows上对其进行测试时,直到我将以下行添加到: 谁能向我解释为什么我在Windows中需要此行,而在Linux服务器上却不需要? 问题答案: SSL证书上的此cURL手册页介绍了连接到SSL / TLS受保护主机时 证书验证 的过程

  • 问题内容: 我有一个将对象保存到数据库的EJB。在我看到的一个示例中,一旦保存了此数据(EntityManager.persist),就会调用EntityManager.flush();。为什么我需要这样做?我要保存的对象未附加,以后在该方法中也不会使用。实际上,一旦保存,该方法就会返回,并且我希望资源会被释放。(示例代码也在remove调用上执行此操作。) 问题答案: 调用将强制数据立即被持久保