焦点

java 解析json 不知道key

时间:2010-12-5 17:23:32  作者:休闲   来源:探索  查看:  评论:0
内容摘要: java 解析json 不知道key 后端对接第三方接口时,最怕遇到这种返回:{"data": {"a": 1, "b": {"c": 2}}},文档里只写“动态字段”,key 是用户自定义的。你总

java 解析json 不知道key

后端对接第三方接口时,解析最怕遇到这种返回:{ "data": { "a": 1,不知 "b": { "c": 2}}},文档里只写“动态字段”,解析key 是不知用户自定义的。你总不能写死十个字段名去 get。解析Java 里没有 JavaScript 那种 Object.keys() 的不知天然便利,但也不是解析没办法。

核心就一句话:用 Map 接收,不知然后遍历 keySet()。解析Jackson 和 Gson 都支持把 JSON 对象直接反序列化成 Map<String,不知 Object>。比如 Jackson 这样写:

ObjectMapper mapper = new ObjectMapper(); Map<String,解析 Object> map = mapper.readValue(jsonStr, new TypeReference<Map<String, Object>>() { }); for (String key : map.keySet()) {  System.out.println(key + ": " + map.get(key)); }

这就拿到了所有顶层 key。但嵌套怎么办?不知比如 data 里面还有一层动态对象。别急,解析Object 类型在 Jackson 里会被解析成 LinkedHashMap,不知所以递归判断 instanceof Map 就能一层层剥开。解析写个递归函数,打印所有叶子节点的路径,比什么 JSONPath 都直观。

Gson 类似,TypeToken<Map<String, Object>> 搞定。区别在于 Gson 默认把数字解析成 Double,如果你在意精度,得自定义 JsonDeserializer。这是后话,但值得记住——我踩过坑,接口返回订单号当数字,超过 16 位,Gson 直接给我变成科学计数法,对接方差点骂人。

另一种场景是 JSON 数组里每个对象结构不同。比如日志系统里,每条日志的附加字段都不一样。这时候用 JsonNode(Jackson)最顺手:

JsonNode root = mapper.readTree(jsonStr); Iterator<Map.Entry<String, JsonNode>> fields = root.fields(); while (fields.hasNext()) {  Map.Entry<String, JsonNode> entry = fields.next(); // entry.getKey() 就是动态 key }

个人更推荐 JsonNode 的方式,因为你可以保留类型信息,node.isInt()、node.isTextual() 判断起来比从 Map 里拿 Object 再强转要干净。尤其是处理 null 值,Map 里 get 出来可能是 null,但你不知道是“key 不存在”还是“值就是 null”,JsonNode 有 has() 方法区分,这细节能救你命。

还有个偏门技巧——如果你只是想知道有哪些 key,不想写循环,可以直接用 mapper.readTree(jsonStr).fieldNames(),返回迭代器,配合 Java 8 的 Iterator.forEachRemaining() 一行打印。但注意,这只是顶层字段,嵌套结构还得递归。

最后说个真实案例。去年做支付回调对接,对方返回的 ext_info 字段里是各种自定义属性,有的 key 带点号,比如 "user.name"。直接按 map 遍历没问题,但如果你用 JSONPath 类似工具(比如 JsonPath.read(json, "$.ext_info.user.name")),会被点号误导成嵌套路径。所以遇到这种脏数据,老老实实遍历 keySet,别走捷径。别问我怎么知道的——生产环境报错日志里全是 PathNotFoundException。

工具选型上,如果你项目已经用了 Jackson(Spring Boot 默认),那就别引 Gson 了。两个库共存除了增加 jar 包体积,没任何好处。而且 Jackson 的 ObjectMapper 可以全局配置,比如 FAIL_ON_UNKNOWN_PROPERTIES 关掉,解析宽松 JSON 时少很多异常。

代码写完了,测试用例别忘。动态 key 场景下,测试数据里至少包含三种情况:空对象、嵌套三层以上、key 含特殊字符。不然你以为写对了,上线被真实数据教做人。

最近更新
热门排行
copyright © 2026 powered by 力不从心网   sitemap