如何在包装类中合并两个spring boot微服务响应 [英] How to merge two spring boot micro-services response in wrapper class

查看:95
本文介绍了如何在包装类中合并两个spring boot微服务响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚接触 Spring Boot 微服务并探索 webflux 框架.我正在尝试将来自两个微服务的响应合并到一个包装类,以便以正确的 JSON 格式提供响应.下面是详细的场景.

微服务1:http://localhost:8080/products在这个微服务的控制器中,它返回了 Flux,我得到了

<预><代码>[{"id": "5b2fd1e5f57d731904c54ad7","name": "Product3",价格":30"},{"id": "5b2fd1e4j9fdj3kds9djkj43","name": "Product2",价格":20"}]

微服务2:http://localhost:8181/person在第二个服务的控制器中,它返回 Mono,为此我也得到了正确的响应,如下所示,

<代码>{id":ehj8u3jmodmdj,"name": "PersonXXX","email": "PersonXXX@somecorp.com"}

现在我想创建另一个微服务 http://localhost:8282/personproduct 应该结合结果包装类中的上述两个微服务如下,

<代码>{{id":ehj8u3jmodmdj,"name": "PersonXXX","email": "PersonXXX@somecorp.com"},[{"id": "5b2fd1e5f57d731904c54ad7","name": "Product3",价格":30"},{"id": "5b2fd1e4j9fdj3kds9djkj43","name": "Product2",价格":20"}]}

现在我有一个 Product 和 Person 类的父类实体,我通过 WebClient 调用上述两个微服务并使用 Flux.concat(personResp, productResp); 连接响应.其中 personResp 是 Mono 类型,productResp 是 Fl​​ux 类型,但我只在文本中而不是在 JSON 中收到此(第三个)微服务的响应,如下所示,

data:{"id":ehj8u3jmodmdj,"name":"PersonXXX","email":"PersonXXX@somecorp.com"}数据:{"id":"5b2fd1e5f57d731904c54ad7","name":"Product3","price":"30"}数据:{"id":"5b2fd1e4j9fdj3kds9djkj43","name":"Product2","price":"20"}

这可能是因为每个元素都作为不同的流发送.

所以只想知道是否有任何方法可以在一个包装类中组合两个响应,而无需在对这两个服务进行的任何调用上使用 block() 方法.

更新

目前我将产品微服务称为,

clientProd.get().uri(productUrl).header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).retrieve().bodyToFlux(Product.class).onErrorReturn(new Product());

与个人服务类似,

clientPerson.get().uri(personUri).header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).retrieve().bodyToMono(Person.class).onErrorReturn(new Person());

连接是使用 Flux.concat(),

提前致谢.

解决方案

正确的方法是将这些响应映射到类:

公共类产品{私人长ID;私人字符串名称;私人双倍价格;//构造函数,getter,setter}公共类人{私人长ID;私人字符串名称;私人字符串邮件;//构造函数,getter,setter}公共类实体{私人 人 人;私人列表<产品>产品;//构造函数,getter,setter}

通过这种方式,您可以根据需要(您正在调用的 API 类型)使用三种不同的 POJO.

I new to Spring boot microservices and exploring webflux framework. I'm trying to merge response from two microservices to one wrapper class to have the response in proper JSON. Below is the scenario in detail.

Micro-Service 1 : http://localhost:8080/products in controller of this micro-service its returning Flux and I'm get

[
    {
        "id": "5b2fd1e5f57d731904c54ad7",
        "name": "Product3",
        "price": "30"
    },
    {
        "id": "5b2fd1e4j9fdj3kds9djkj43",
        "name": "Product2",
        "price": "20"
    }
]

Micro-Service 2 : http://localhost:8181/person In controller of second service its returning Mono and for this also I'm getting correct response as below,

{
    "id": ehj8u3jmodmdj,
    "name": "PersonXXX",
    "email": "PersonXXX@somecorp.com"
}

Now I want to create another microservice http://localhost:8282/personproduct which should combine the result of above two microservices in a wrapper class as below,

{
    {
        "id": ehj8u3jmodmdj,
        "name": "PersonXXX",
        "email": "PersonXXX@somecorp.com"
    },

    [
        {
            "id": "5b2fd1e5f57d731904c54ad7",
            "name": "Product3",
            "price": "30"
        },
        {
            "id": "5b2fd1e4j9fdj3kds9djkj43",
            "name": "Product2",
            "price": "20"
        }
    ]

}

Right now I have a Parent class Entity for both Product and Person classes and I'm calling both above mentioned micro-services via WebClient and concatinating the response using Flux.concat(personResp, productResp); where personResp is of type Mono and productResp is of type Flux but I'm getting response of this (3rd) microservice only in Text and not in JSON as below,

data:{"id":ehj8u3jmodmdj,"name":"PersonXXX","email":"PersonXXX@somecorp.com"}
data:{"id":"5b2fd1e5f57d731904c54ad7","name":"Product3","price":"30"}
data:{"id":"5b2fd1e4j9fdj3kds9djkj43","name":"Product2","price":"20"}

This might be due to each element is sent as a different stream.

So just want to know if is there any way to combine two responses in one wrapper class without using block() method on any of the calls done to these two services.

UPDATE

Currently Im calling product microservice as,

clientProd.get().uri(productUrl)
                .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .retrieve().bodyToFlux(Product.class).onErrorReturn(new Product());

And similarly Person service as,

clientPerson.get().uri(personUri)
                .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .retrieve().bodyToMono(Person.class).onErrorReturn(new Person());

And concatenating is using Flux.concat(),

Thanks in advance.

解决方案

The correct way is to map those responses to classes:

public class Product{
    private Long id;
    private String name;
    private Double price;

    //constructors, getters, setters
}

public class Person{
    private Long id;
    private String name;
    private String mail;

    //constructors, getters, setters
}

public class Entity{
    private Person person;
    private List <Product> products;

    //constructors, getters, setters
}

In this way you have three different POJOs that you can use according to the needs (the type of API you are calling).

这篇关于如何在包装类中合并两个spring boot微服务响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆