充实 Collection

Enriching Collection

我想用个人详细信息丰富 collection 订单。

假设我已经(示例在 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"
   }
]

根据这些信息,我需要用人物详细信息丰富每个 objects,所以最终结果将是这样的:

[
   {
      "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"
      }
   }
]

是否可以使用增强剂来实现这一目标?

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

您所询问的关于丰富 JSON 字符串的任务有点不寻常,并且超出了 Spring 集成范围。我只能建议实现一些服务方法来接受JSON,做解析、迭代和修改。在方法的末尾,您将生成所需的 JSON。这个真的可以用来从 @ServiceActivator 监听 enrich request 消息通道和 return 回复 replyChannel header.

如何进行 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());
    }

更新2

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

如果你原来的列表确实是JSON,我们可以这样做:

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

jsonPath 提取所有 buyerId 属性并生成它们值的 List

getBuyersChannel 流程必须执行一些查询和 return,例如 Map<String, String> - buyerId -> buyer_as_json。这个结果将被存储在上面提到的 buyers header.

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

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

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

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