【问题标题】:Spring-Webflux: Extracting Object from Mono without block()Spring-Webflux:从 Mono 中提取对象而不使用 block()
【发布时间】:2020-07-26 22:31:17
【问题描述】:

我是新的 Spring Webflux。我正在编写一个简单的 api,它调用另一个 api 并返回响应。 我遇到的问题是我的 api 接受的请求类型与外部 api 不同。我必须将传入的请求转换为发送到外部 api。我正在使用 Mono 来接收对我的 api 的请求,但是在没有的情况下无法转换为另一个对象块()。

输入

路由器

@Configuration
@EnableWebFlux
public class RouterConfig implements WebFluxConfigurer{

    @Bean
    public RouterFunction<ServerResponse> routes(UserHandler handler){
        
        return RouterFunctions
                .route(POST("/rest/create"),
                        handler::createUser);
    }
    
} 

处理程序

@Component
public class UserHandler {

    private UserService service;

    public UserHandler(UserService service) {
    this.service = service;
    }

      
    public Mono<ServerResponse> saveUser(ServerRequest request) 
    {
    
        Mono<User> user = request.bodyToMono(User.class)
    
        /* currently I am using block to get User object */
    
         User user1 = user.block()
    
        /* convert user to person */
       
           Person p =getPersonFromUser(user);
    
       
    
        
    }

Pojos

 class User
    {
      private String name;
      private String id;
      private String email;
       private String phone;    
    
    
    }



 class Person
    {
      private String email;
      /* Combination of id and name */
      private String accountNumber;
      private String phone;
    
    }

有没有办法可以将 Mono 转换为 Person 对象而不阻塞?

【问题讨论】:

    标签: java spring rest spring-webflux project-reactor


    【解决方案1】:

    如果您愿意在 Mono-Lambda 中处理 Person p,那么您可以尝试

    public Mono<ServerResponse> saveUser(ServerRequest request) 
    {
        // Mono<User> user = request.bodyToMono(User.class)
        request.bodyToMono(User.class)
    
        // Convert a Mono<User> to a Mono<Person>    
        .map((User user1) -> getPersonFromUser(user))
    
        .map((Person p) -> {
            // Code that either returns ServerResponse object or an intermediary object
        })
        // Additional code as needed
    

    因为 request.bodyToMono(User.class) 返回一个用户的 Mono,你可以调用 Mono 的 map 方法。 map 方法接受 Function 类型的 lambda,它接受一种类型的参数并返回不同类型的对象。

    第一次调用地图:

    .map((User user1) -> getPersonFromUser(user))
    

    给定了一个 Lambda,它接受一个将 User 转换为 Person 的函数,因此我从“Mono for User”跳到了“Mono for人”。

    我不知道是否有办法直接从 Person 获取 ServerResponse 但在第二个 map 调用中,您可以编写函数以返回一个 ServerResponse (在这种情况下,您有一个“ServerResponse 的单声道”并且您基本上完成了)或返回另一个中间对象。如果您执行后者,您可能需要额外的映射调用。

    注意:如果在您的 Lambda 中,您得到一个 Mono,您需要使用 flatMap 方法,即如果 getPersonFromUser(user) 返回一个 Mono 的Person 代替 Person,然后代替

    .map((User user1) -> getPersonFromUser(user))
    

    你会使用

    .flatMap((User user1) -> getPersonFromUser(user))
    

    如果您对 mapflatmap

    感兴趣,可以查看此 StackOverFlow Question

    【讨论】:

    • 感谢您的回复。因此,如果我们在响应式中编写所有内容,那么可以选择 flatmap 吗?
    • 这是一个选项,但它应该在传入它的 lambda 返回给定类型 T 的 Mono 时使用。否则,如果 lambda 返回常规类型,则应使用 "地图”
    猜你喜欢
    • 2020-04-30
    • 1970-01-01
    • 2021-01-28
    • 2019-12-14
    • 1970-01-01
    • 2020-10-05
    • 2021-07-14
    • 1970-01-01
    • 2021-08-14
    相关资源
    最近更新 更多