首页 > 解决方案 > 从 Mono 返回 Java 对象

问题描述

我正在尝试从 Mono 获取 Json String。我尝试使用 block() 方法来获取对象它工作正常,但是当我使用 map/flatmap 时,我没有看到以下代码行被执行。我看到帐户 Mono 不为空。

private String getJsonString( Mono<Account> account) {
        response.map(it->{
           **// call is not coming here** 
            val json = mapper.writeValueAsString(it)
            System.out.println(son)
        });
    }

我在这里做错什么了吗?

标签: javaspringjava-streamspring-webfluxreactor

解决方案


如果您阅读官方文档,您会看到:

在您订阅之前什么都不会发生

现在明白了,在基于 Spring Boot WebFlux 的微服务中,订阅者是谁?,看看这个stackoverflow问题

现在,如果您认为,您可以在同一个服务中拥有blockingreactive实现,不幸的是,它不是那样工作的。为此,您必须了解反应器工作的事件循环模型。block因此,在流程中的任何点调用方法都没有好处,相当于使用旧的阻塞 spring-web 方法。因为正在处理请求的线程被阻塞并等待 I/O 操作/网络调用的结果。

在评论中提出您的问题:

但是当我在我的控制器中使用 flatMap 来调用处理程序方法时,它会使用 Object 而不是 mono?serviceRequest-->Mono-->Object 的服务方法这是如何工作的?

让我给你一个简单的例子:

假设您有一个员工应用程序,您想在其中获取给定 ID 的员工详细信息。现在在您的控制器中,您将拥有这样的端点:

@GetMapping("/{tenant}/api/employee/{id}")
  public Mono<ResponseEntity> getEmployeeDetails(@PathVariable("id") Long employeeId) {
    return employeeService.getDetails(employeeId)
        .map(ResponseEntity::ok);
  }

现在为您服务,

  public Mono<EmployeeEntity> getDetails(Long employeeId) {
    return employeeRepository.findById(employeeId);
  }

您的存储库将如下所示:

@Repository
public interface EmployeeRepository extends ReactiveCrudRepository<EmployeeEntity, Long> {

}

推荐阅读