java - 如何使用 Jackson 递归地修改 JsonNode 的值
问题描述
要求:
我想对JsonNode
. 功能可以不同,例如:-lowercasing
一些值或将某些内容附加到这些值或用某些内容替换这些值。我怎样才能使用Jackson
库来实现呢?请注意,JSON 数据的结构可能不同,这意味着我想构建一个通用系统,该系统将接受一些路径表达式,该路径表达式基本上将决定更改的位置。我想使用函数式编程风格,以便可以将这些函数作为参数传递。
例如:
输入:
{
"name": "xyz",
"values": [
{
"id": "xyz1",
"sal": "1234",
"addresses": [
{
"id": "add1",
"name": "ABCD",
"dist": "123"
},
{
"id": "add2",
"name": "abcd3",
"dist": "345"
}
]
},
{
"id": "xyz2",
"sal": "3456",
"addresses": [
{
"id": "add1",
"name": "abcd",
"dist": "123"
},
{
"id": "add2",
"name": "XXXXX",
"dist": "345"
}
]
}
]
}
在这种情况下,我基本上必须有两个功能,lowercase()
并且convert_to_number()
. 我想对each中的所有属性应用lowercase()
函数。同样适用于,但适用于所有属性。"name"
"addresses"
"value"
convert_to_number()
"dist"
因此,基本上,JSON
函数的表达式如下所示:
lowercase() : /values/*/addresses/*/name
convert_to_number() : /values/*/addresses/*/dist
输出:
{
"name": "xyz",
"values": [
{
"id": "xyz1",
"sal": "1234",
"addresses": [
{
"id": "add1",
"name": "abcd",
"dist": 123
},
{
"id": "add2",
"name": "abcd3",
"dist": 345
}
]
},
{
"id": "xyz2",
"sal": "3456",
"addresses": [
{
"id": "add1",
"name": "abcd",
"dist": 123
},
{
"id": "add2",
"name": "xxxx",
"dist": 345
}
]
}
]
}
客户端代码:
JsonNode jsonNode = ...
applyFunctionsRecursivelyBasedOnExpr(JsonNode jsonNode, String expr, Function )
解决方案
正如@MichalZiober 在他的回答中已经指出的那样,当您需要执行基于 JSON 路径的操作时, JsonPath提供了比杰克逊更强大的 API。
使用方法JsonPath.parse
,WriteContext.map
您只需几行就可以解决您的问题:
import java.io.File;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath;
public class Main {
public static void main(String[] args) throws Exception {
File file = new File("input.json");
String json = JsonPath.parse(file)
.map("$.values[*].addresses[*].name", Main::lowerCase)
.map("$.values[*].addresses[*].dist", Main::convertToNumber)
.jsonString();
System.out.println(json);
}
private static Object lowerCase(Object currentValue, Configuration configuration) {
if (currentValue instanceof String)
return ((String)currentValue).toLowerCase();
return currentValue;
}
private static Object convertToNumber(Object currentValue, Configuration configuration) {
if (currentValue instanceof String)
return Integer.valueOf((String)currentValue);
return currentValue;
}
}
推荐阅读
- android - Android键盘工具栏通过调整调整大小切断了视图的底部
- json - 解析 Multipart/Form 消息并处理
- reactjs - 如何使用 outsideClick 功能到另一个文件模态元素
- ruby-on-rails - Resque 工作人员命令未显示任何信息
- css - 如何使用 Material UI 表格设置一个粘性页脚?
- node.js - 如何将 string[] 作为参数传递给solidity函数?
- azure - AzureAD Powershell 列出所有可用角色而不是分配的角色
- excel - Excel - 查找值
- swift - DateFormatter() 与双类型秒 swift
- jenkins - 我如何使用 jenkins 将应用程序部署到多个服务器