
本文介绍一种简洁高效的方式,利用 Josson 库的 map() 查询表达式,根据指定 JSON 路径(如 "$.a.a2"、"$.c")从原始 JSON 中提取并重构仅含目标字段的新对象,避免手动遍历、路径去重与深层结构构建等复杂逻辑。
本文介绍一种简洁高效的方式,利用 josson 库的 `map()` 查询表达式,根据指定 json 路径(如 `"$.a.a2"`、`"$.c"`)从原始 json 中提取并重构仅含目标字段的新对象,避免手动遍历、路径去重与深层结构构建等复杂逻辑。
在 JSON 数据处理中,常需按需“投影”(projection)原始对象——即保留特定路径下的字段,剔除其余无关内容。Jayway JsonPath 虽强大,但原生不支持声明式字段过滤与结果结构重建;其 read() 仅返回值,set() 又缺乏自动嵌套建模能力,导致开发者不得不自行实现路径归一化、父节点预创建、深度拷贝等繁琐逻辑。
此时,Josson 提供了一种更优雅的替代方案。它专为 JSON 查询与转换设计,语法简洁,内置 map() 函数可直接按层级关系声明输出结构,天然支持嵌套路径投影与对象重组。
例如,针对原始 JSON:
{
"a": {"a1": 1, "a2": 2},
"b": "foo",
"c": []
}
若只需保留 $.a.a2 和 $.c,使用 Josson 的查询表达式 "map(a.map(a2), c)" 即可一步生成目标结果:
import com.octomix.josson.Josson;
import com.fasterxml.jackson.databind.JsonNode;
Josson josson = Josson.fromJsonString(
"{" +
" \"a\": {\"a1\": 1, \"a2\": 2}," +
" \"b\": \"foo\"," +
" \"c\": []" +
"}");
JsonNode result = josson.getNode("map(a.map(a2), c)");
System.out.println(result.toPrettyString());
输出为:
{
"a": {
"a2": 2
},
"c": []
}
该表达式语义清晰:外层 map() 定义最终对象的顶层字段;a.map(a2) 表示在 "a" 字段下再执行一次 map,仅保留其子字段 "a2";而独立的 c 则直接将顶层 "c" 原样纳入结果。Josson 自动处理空值、缺失路径(静默忽略)及嵌套对象初始化,无需额外容错代码。
⚠️ 注意事项:
- Josson 依赖 Jackson 作为底层解析器,需确保项目已引入
com.fasterxml.jackson.core:jackson-databind; - 查询表达式使用点号(
.)而非$前缀,路径基于当前上下文,更接近 JavaScript 风格,学习成本低; - 不支持通配符路径(如
a.*)的动态投影,若需此类能力,建议结合预处理或切换至支持自定义转换器的库(如 Jolt); - 当前最新版(v1.7+)已稳定支持 Java 11+ 与模块化环境,GitHub 仓库持续维护,非已弃用项目。
综上,对于确定路径列表的 JSON 字段过滤场景,Josson 的 map() 表达式是比手动实现或 Jayway + 多步操作更安全、简洁、可读性更强的专业级解决方案。











