原文出处:
琴水玉
背景与问题
在 《一个略复杂的数据映射聚合例子及代码重构》 一文中,将一个JSON字符串转成了所需要的订单信息Map。尽管做了代码重构和配置化,过程式的代码仍然显得晦涩难懂,并且客户端使用Map也非常难受。
能不能把这个JSON串转成相应的对象,更易于使用呢? 为了方便讲解,这里重复写下JSON串。
{ "item:s_id:18006666": "1024", "item:s_id:18008888": "1024", "item:g_id:18006666": "6666", "item:g_id:18008888": "8888", "item:num:18008888": "8", "item:num:18006666": "6", "item:item_core_id:18006666": "9876666", "item:item_core_id:18008888": "9878888", "item:order_no:18006666": "E20171013174712025", "item:order_no:18008888": "E20171013174712025", "item:id:18008888": "18008888", "item:id:18006666": "18006666", "item_core:num:9878888": "8", "item_core:num:9876666": "6", "item_core:id:9876666": "9876666", "item_core:id:9878888": "9878888", "item_price:item_id:1000": "9876666", "item_price:item_id:2000": "9878888", "item_price:price:1000": "100", "item_price:price:2000": "200", "item_price:id:2000": "2000", "item_price:id:1000": "1000", "item_price_change_log:id:1111": "1111", "item_price_change_log:id:2222": "2222", "item_price_change_log:item_id:1111": "9876666", "item_price_change_log:item_id:2222": "9878888", "item_price_change_log:detail:1111": "haha1111", "item_price_change_log:detail:2222": "haha2222", "item_price_change_log:id:3333": "3333", "item_price_change_log:id:4444": "4444", "item_price_change_log:item_id:3333": "9876666", "item_price_change_log:item_id:4444": "9878888", "item_price_change_log:detail:3333": "haha3333", "item_price_change_log:detail:4444": "haha4444" }
思路与实现
要解决这个问题,需要有一个清晰的思路。
- 首先,需要知道应该转成怎样的目标对象。
- 其次,需要找到一种方法,建立从JSON串到目标对象的桥梁。
推断目标对象
仔细观察可知,每个 key 都是 tablename:field:id 组成,其中 table:id 相同的可以构成一个对象的数据; 此外,不同的tablename 对应不同的对象,而这些对象之间可以通过相同的 itemId 关联。
根据对JSON字符串的仔细分析(尤其是字段的关联性),可以知道: 目标对象应该类似如下嵌套对象:
@Getter @Setter public class ItemCore { private String id; private String num; private Item item; private ItemPrice itemPrice; private List<ItemPriceChangeLog> itemPriceChangeLogs; } @Getter @Setter public class Item { private String sId; private String gId; private String num; private String orderNo; private String id; private String itemCoreId; } @Getter @Setter public class ItemPrice { private String itemId; private String price; private String id; } @Getter @Setter public class ItemPriceChangeLog { private String id; private String itemId; private String detail; }
注意到,对象里的属性是驼峰式