java - 丰富 Collection

标签 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"
      }
   }
]

是否可以使用丰富器来实现此目的?

最佳答案

嗯,ContentEnricher正是因为这个原因。您收到一条消息,发送丰富的请求,等待回复并生成输出。

您所询问的有关丰富 JSON 字符串的问题是一项有点不寻常的任务,并且超出了 Spring Integration 的范围。我只能建议实现一些服务方法来接受 JSON,进行解析、迭代和修改。在方法的最后,您将生成所需的 JSON。这个确实可以用@ServiceActivator监听丰富请求消息 channel 并返回回复 replyChannel header 。

如何进行 JSON 解析等对我来说似乎超出了问题范围。不过,我建议您查看 JsonToObjectTransformer获得 List一些要迭代和修改的 POJO。然而一个简单的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他们的值(value)观。

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

此后.enrich()你需要写一个自定义.transform()编码并迭代 buyers header 并执行 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<?, ?>>您可以执行类似的迭代来扩展与买家的订单 map 。

关于java - 丰富 Collection ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49424895/

相关文章:

java - Spring Integration 应用程序未使用 ActiveMQ 队列

java - JTextField 和 JLabel 未出现

java - 将 csv 数据从存储导入 Cloud SQL 不起作用 - 状态始终为 "pending"

java - 从地理名称实现 Google API 搜索

java - Spring OAuth2 安全单元测试

java - Spring 中的自定义 Auth 用户

java - 适当使用 Spring Integration Java DSL 加上 AmazonS3InboundSynchronizationMessageSource

java - 从 JMS header 获取字符串值

java - 作业重启异常 : JobInstance already exists and is not restartable

java - Spring http出站网关希望使用PollableChannel而不是DirectChannel