业务需要按照”response. customerInfo.children“来获取到每个 children 节点 list 并需要包含该节点的所有父节点及其属性(理论上好像只要在解析的时候将父节点传进来即可,因为子节点确定了那他的父节点肯定也是确定的,不存在 list 的问题),想了半天没有想出来,请各位大佬支支招!
原 json:
{ "response": { "customerInfo": [ { "uuid": "59a49249342f4262bd59ea2e36ac40d3", "name": "张三", "phoneNo": "15566669999", "idCard": "123456789965412544545", "wife": { "uuid": "51e211b7d1e54578b0093a5418868aa6", "name": "李四", "phoneNo": "15566668888", "idCard": "1236547896513245" }, "children": [ { "uuid": "8e1b40a3bc4a4f709a7076002132c7e3", "name": "张五", "phoneNo": "15523645896", "idCard": "523641528965425" }, { "uuid": "cd73bd47b6a945e0b3ca86927a154c1b", "name": "张六", "phoneNo": "15562458952", "idCard": "652154258962541" } ] }, { "uuid": "c752f9ff5a0d4776880e8ea1f0fcc482", "name": "王五", "phoneNo": "13652366548", "idCard": "123654856525665" } ] } }
解析后需要得到的 list
[ { "response": { "customerInfo": { "uuid": "59a49249342f4262bd59ea2e36ac40d3", "name": "张三", "phoneNo": "15566669999", "idCard": "123456789965412544545", "wife": { "uuid": "51e211b7d1e54578b0093a5418868aa6", "name": "李四", "phoneNo": "15566668888", "idCard": "1236547896513245" }, "children": { "uuid": "8e1b40a3bc4a4f709a7076002132c7e3", "name": "张五", "phoneNo": "15523645896", "idCard": "523641528965425" } } } }, { "response": { "customerInfo": { "uuid": "59a49249342f4262bd59ea2e36ac40d3", "name": "张三", "phoneNo": "15566669999", "idCard": "123456789965412544545", "wife": { "uuid": "51e211b7d1e54578b0093a5418868aa6", "name": "李四", "phoneNo": "15566668888", "idCard": "1236547896513245" }, "children": { "uuid": "cd73bd47b6a945e0b3ca86927a154c1b", "name": "张六", "phoneNo": "15562458952", "idCard": "652154258962541" } } } } ]
就相当于是把每个子节点单独拿出来和他的各级父节点组成一个 JsonObject ,大佬们有没有什么妙招哇
![]() | 1 blankmiss 2023-08-10 14:04:34 +08:00 转成对象然后操作 |
3 lyxeno 2023-08-10 14:08:57 +08:00 你就正常创建一个 CustomerInfo 实体类拿 jackson 去反序列化生成出实体类后, 再根据你需要得到的形态去构建对象,然后 jackson 序列化为 json 就好了 ```java @Data class CustomerInfo{ String uuid; String name; /* 其他属性 */ List<CustomerInfo> children; CustomerInfo wife; } ``` |
4 lyxeno 2023-08-10 14:10:03 +08:00 实在不行反序列化成 Map 去做处理也可以的。就是丑陋了点 |
![]() | 5 darkengine 2023-08-10 14:12:17 +08:00 格式不固定也得有规律吧,用个 type 之类的参数代表不行么 |
6 thebeacon OP @darkengine 产品就是要整一个无敌通用,什么 json 进来我们都要根据一个 key 来拆分出多个子节点列表(包含所有唯一父节点内容) |
![]() | 8 YepTen 2023-08-10 14:52:16 +08:00 用 JSON 的 tree model 试试 |
9 thinkershare 2023-08-10 15:09:12 +08:00 @thebeacon 各个 json 库不是都有自己的未解析的 Json Object 吗?按照 JSON 可能的格式逐个扫描吧。再不行你自己写个 json 序列&反序列化器好了,反正也不是什么难事,这样性能反正也不会好到哪里去,所以完全不需要考虑 JSON 库的性能优化。 |
![]() | 10 6IbA2bj5ip3tK49j 2023-08-10 15:25:11 +08:00 循环 jsonnode 的节点,然后根据是不是 array 做判断处理,递归下去即可。 你需要确定你的规则。 比如,父节点的兄弟节点也是数组,期望得到什么样的结果? { "keyA": [ { "name": "M" }, { "name": "N" } ], "keyB": [ { "name": "O" }, { "name": "P" } ] } |
![]() | 11 gogo789 2023-08-10 15:59:01 +08:00 这个 json 有点混乱了。首先会有一个 customerInfoDTO.java 里面包含 uuid,name,phoneNo...字段和 wife.java,children.java 两个对象。你直接通过 JSONObject.parseObject(jsonStr,customerInfoDTO.class) 除了 children 都可以解析到,关于 children 就只能自己手动处理了。可以通过 jsonObject.getJSONObject("response").getJSONArray("customerInfo").getJSONObject(0).getJSONArray("children") 获取到一个 children 的 jsonArray ,然后手动遍历解析这个 Array ,复制上面的解析结果往里面填充 children |
![]() | 12 Dlin 2023-08-10 16:04:33 +08:00 可以先转为 ObjectNode,再根据属性来重新构建新的 ObjectNode |
![]() | 13 xinxingi 2023-08-10 16:45:49 +08:00 @thebeacon 考虑到你的 json 格式不固定,那就简单粗暴一点。拿到原 json 后,把原 json 的 response. customerInfo.children 全部拿出来装入集合。清空原 json 中的 response. customerInfo.children.拿刚才的集合一个一个的全部遍历填充进去。结束 |
14 bill110100 2023-08-10 17:01:12 +08:00 @thebeacon 那你只能和产品怼,要不改需求,要不给开放时间,或者干脆要求换语言框架,理由很明确,java 强类型语言,不可能做到灵活多变的参数系统, 还有,如果数据类型可以有某些特殊的字段,或者可以给你传输一些可以辨别格式的字段的话,可以通过多态的形式来转换,jackson 有做多态转换的注解,根据传输的参数是否有某字段为判断条件,将 json 反序列化为某一个父类下的不同子类。 @JsonTypeInfo @JsonSubTypes 这几个注解可以看一下。 |
![]() | 15 JinTianYi456 2023-08-10 17:37:58 +08:00 JSON.parseObject("") .getJSONObject("response") .getJSONArray("customerInfo") .stream() .map(t -> Collections.singletonMap("response", Collections.singletonMap("customerInfo", t))) .collect(Collectors.toList()); 这样? |
16 Corolin 2023-08-10 17:39:41 +08:00 好像 JsonPath 可以 反过来一层层去取?$.response.customerInfo[*] https://jsonpath.com/ |
![]() | 17 c3de3f21 2023-08-10 18:13:10 +08:00 得需要个 type 字段。。。 |
![]() | 18 c3de3f21 2023-08-10 18:13:34 +08:00 或者说需要一些 描述 json 本身的字段才行。 |
![]() | 19 mmdsun 2023-08-11 12:52:34 +08:00 via iPhone 转对象处理,动态的用在对象里面用 map 声明 @JsonAnyGetter 、 @JsonAnySetter 即可。 |