【问题标题】:Cherry pick attributes from an object in a generic way以通用方式从对象中挑选属性
【发布时间】:2020-04-07 03:29:15
【问题描述】:

我想构建一个数据聚合器,它调用多个服务并从它们的响应中提取一些属性,然后构建聚合对象。

请考虑以下示例:
要获取订单详情,我需要调用 OrderService 的 GetOrderDetails API,它会返回以下输出(简化版):

{
   statusCode: OK,
   orderDetails: {
      orderId: "order_id",
      offer: {
         offerId: "offer_id",
         offerType: "offer_type"
      },
      address: {
         addressId: "address_id",
         houseNo: "house_no",
         city: "city",
         state: "state"
      }
   }
}

同样,我需要调用其他服务。

问题
我需要通过从这些服务的响应中挑选属性来构建输出对象无需通过相关属性的获取器对逻辑进行硬编码

我计划将所需属性的列表及其各自的路径存储为配置,然后提取逻辑将是通用的。

好吧,配置看起来像:
output_attribute: dotted_hierarchy_path
orderId:orderDetails.orderId
addressId:orderDetails.address.addressId

所以,我的输出对象将是:

{
    orderId: <order_id>,
    addressId: <address_id>
}

如果我有这种配置,我的 java 代码将是通用的,即它可以从任何对象中挑选任何属性。

要提取所需的属性,我的想法是遍历虚线路径并通过Java反射获取值。但是 Java 反射很慢。

这是一个实际的世界问题,因此希望人们提出他们有价值的方法。

【问题讨论】:

  • @Turing85:我已经通过配置提出了解决问题的方法,该配置通过虚线路径和 Java 反射存储层次结构。如果有人有,这里的要求是提出更好的方法。
  • @Turing85:这是一个实际的世界问题,可以有多种方法,所以想和stackoverflow社区讨论。谢谢。
  • @Turing85:完成。
  • 谢谢 :) 我的 cmets 很快就会自毁。

标签: java aggregation soa


【解决方案1】:

正如你所说,反思是缓慢而棘手的。我不会尝试从头开始重新实现它,而是使用现有的库,例如FasterXML/jackson。我暂时不用担心性能。

一般来说,我会尝试将对象转换为嵌套地图。如果您可以访问纯 json,则无需将它们映射到对象,这样您就可以跳过反射:

Map<String, Object> root = objectMapper.readValue(json, new TypeReference<Map<String, Object>>() {});

如果你必须处理对象,你可以用类似的方式将它们转换为嵌套地图:

Map<String, Object> root = objectMapper.convertValue(object, new TypeReference<Map<String, Object>>() {});

通过 dotted_hierarchy_path 从嵌套地图中获取值应该很容易。

【讨论】:

  • 我有很重的对象、很多字段、很多层次结构等,所以使用 Map 会消耗内存。我知道,map 减少了解决这个问题的努力,但代价是大量内存用于重物。感谢您的宝贵方法:)
  • @Azim 你可能是对的,但我会采取最简单的方法来实现概念验证。我认为,您将在途中面临更严重的问题,例如如果您需要根据对象 A 中的值从对象 B 中提取字段。您最终会在配置中使用一种自定义迷你语言,虚线层次结构路径是不够的。同样,我会寻找现成的解决方案,可能是 JSONPath 等。或者像 Groovy 这样的动态语言在这里会更好。
  • 是的,我已经研究过 JSONPath,这对我来说似乎是一个很好的解决方案。 jsonpath.com
  • 能否请您在答案中包含 JSONPath 和 JSONPatch,以便我接受?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-08
  • 1970-01-01
相关资源
最近更新 更多