丰富收藏

时间:2018-03-22 09:26:52

标签: java spring spring-integration spring-messaging eai

我想通过人员详细信息丰富订单的收集。

假设我(例如在json中):

[
   {
      "orderId": 123,
      "quantity": 5,
      "buyerId": "84aa820f-2301-4d01-8c4c-2b71204da7dd" 
   },
   {
      "orderId": 124,
      "quantity": 5,
      "buyerId": "7158a748-dfd0-47e5-b620-e8ca4d3ac84d" 
   }
]

现在我想提取所有买家标识符以打到其他消息端点,所以我会得到结果:

[
   {
       "personId": "84aa820f-2301-4d01-8c4c-2b71204da7dd",
       "name": "Johny",
       "surname": "Bravo"
   },
   {
       "personId": "7158a748-dfd0-47e5-b620-e8ca4d3ac84d",
       "name": "Felica",
       "surname": "Good"
   }
]

有了这些信息,我需要用人员细节丰富每个对象,所以最终的结果将是这样的:

[
   {
      "orderId": 123,
      "quantity": 5,
      "buyerId": "84aa820f-2301-4d01-8c4c-2b71204da7dd",
      "buyer": {
         "personId": "84aa820f-2301-4d01-8c4c-2b71204da7dd",
         "name": "Johny",
         "surname": "Bravo"
      }
   },
   {
      "orderId": 124,
      "quantity": 5,
      "buyerId": "7158a748-dfd0-47e5-b620-e8ca4d3ac84d",
      "buyer": {
         "personId": "7158a748-dfd0-47e5-b620-e8ca4d3ac84d",
         "name": "Felica",
         "surname": "Good"
      }
   }
]

使用浓缩物可以达到这个目的吗?

1 个答案:

答案 0 :(得分:1)

嗯,ContentEnricher正是出于这个原因。您收到消息,发送充实请求,等待回复并生成输出。

关于丰富JSON字符串的问题是一个不寻常的任务,来自Spring Integration范围。我只能建议实现一些服务方法来接受JSON,进行解析,迭代和修改。在方法结束时,您将生成所需的JSON。这个实际上可以从@ServiceActivator中使用来监听丰富请求消息通道并返回对replyChannel标题的回复。

如何对我进行JSON解析等似乎是不可能的范围。不过,我建议您查看JsonToObjectTransformer以获取某些POJO的List进行迭代和修改。但是,每条记录的简单Map也足够了。要从List<Map>转换回JSON,您可以考虑使用ObjectToJsonTransformer

<强>更新

如果您能够将JSON转换为List<POJO>List<Map>,则splitter-aggregator模式适合您。

我会这样做,但是:

    @Bean
    public IntegrationFlow enrichJson() {
        return f -> f
                .transform(Transformers.fromJson(List.class))
                .split()
                .channel(c -> c.executor(Executors.newCachedThreadPool()))
                .enrich(e -> e
                        .requestPayloadExpression("payload.buyerId")
                        .requestChannel(getBuyerChannel())
                        .propertyExpression("buyer", "payload"))
                .aggregate()
                .transform(Transformers.toJson());
    }

<强> UPDATE2

例如,如果您希望在一个数据库中获得买家列表,那么让我们考虑这个解决方案。

如果您的原始列表真的是JSON,我们可以这样做:

     .enrich(e -> e
                    .requestPayloadExpression("#jsonPath(payload, '$.buyerId')")
                    .requestChannel(getBuyersChannel())
                    .headerExpression("buyers", "payload"))

jsonPath提取所有buyerId属性,并生成List个值。

getBuyersChannel流必须执行一些查询并返回,例如Map<String, String> - buyerId -> buyer_as_json。此结果将存储在上述buyers标题中。

在此.enrich()之后,您需要编写自定义.transform()代码并对buyers标头进行迭代并执行String.replaceFirst("(\" + buyer.getKey() + \",)", "$1" + buyer.getValue())

如果您的JSON已经是List<POJO>List<Map>,您可以使用类似的方法,但使用Java 8 Streams:

.<List<Map<?, ?>>>requestPayload(m ->
            m.getPayload()
                    .stream()
                    .map(entry -> entry.get("buyerId"))
                    .collect(Collectors.toList()))

数据库的结果可能类似于Map<String, Map<?, ?>>,您可以执行类似的迭代来扩展订单与买家的地图。