英文:
How can I replace a value in json data in Java?
问题
以下是您要翻译的内容:
"I am trying to replace API Data with "All" in Emp_Id field in data in json. And then make rows with every data of API.
I tried in ecmascript but I need in Java as this map function is giving error in nifi.
API DATA: I have stored this data in "Response" attribute in ExtractText in Apache Nifi.
response
{
"status": "success",
"data": [[123, 0], [124, 0], [446, 0], [620, 0], [470 ,1]]
};
jsonData
{
"Emp_Id": "All",
"Emp_loc": "523",
"Emp_dept": "Management",
"Emp_sub_dept": "Finance",
"Emp_sub_dept2": "Accountant"
};
期望结果
[
{
"Emp_Id":"123",
"Emp_loc":"523",
"Emp_dept":"Management",
"Emp_sub_dept":"Finance",
"Emp_sub_dept2":"Accountant"
},
{
"Emp_Id":"124",
"Emp_loc":"523",
"Emp_dept":"Management",
"Emp_sub_dept":"Finance",
"Emp_sub_dept2":"Accountant"
},
{
"Emp_Id":"446",
"Emp_loc":"523",
"Emp_dept":"Management",
"Emp_sub_dept":"Finance",
"Emp_sub_dept2":"Accountant"
},
{
"Emp_Id":"620",
"Emp_loc":"523",
"Emp_dept":"Management",
"Emp_sub_dept":"Finance",
"Emp_sub_dept2":"Accountant"
},
{
"Emp_Id":"470",
"Emp_loc":"523",
"Emp_dept":"Management",
"Emp_sub_dept":"Finance",
"Emp_sub_dept2":"Accountant"
}
]
This is tried in ecmaScript but I want it to be in Java because these functions are not working in executeScript of NIFI and giving error."java.lang.assertionError: geberating bytecode". Or if any other approach for converting this data.
this is the script I tried
var InputStreamCallback = Java.type("org.apache.nifi.processor.io.InputStreamCallback")
var IOUtils = Java.type("org.apache.commons.io.IOUtils");
var OutputStreamCallback = Java.type("org.apache.nifi.processor.io.OutputStreamCallback");
var StandardCharsets = Java.type("java.nio.charset.StandardCharsets");
var Set = Java.type("java.util.HashSet");
var Map = Java.type("java.util.HashMap");
var String = Java.type("java.lang.String");
var flowFile = session.get();
if (flowFile != null) {
var text = ''
session.read(flowFile,
new InputStreamCallback(function (inputStream) {
text = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
}));
var s3Data ={}
var apiResponse={}
var map = new Map();
var s3Data = JSON.parse(flowFile.getAttribute('jsonData'))
var apiResponse = JSON.parse(flowFile.getAttribute('response'))
var result = apiResponse.data.map(([id]) =>
Object.fromEntries(Object.entries(s3Data).map(([k, v]) =>
[k, v === "All" ? id : v]
))
);
flowFile = session.write(flowFile,
new OutputStreamCallback(function(outputStream) {
outputStream.write(JSON.stringify(result).getBytes(StandardCharsets.UTF_8))
})
);
}
I tried with groovy also but I have very less knowledge of Groovy so I couldn't write the proper ExecuteScript."
请注意,由于您提供的原始内容包含HTML实体编码(如"),我已将其保留在翻译中,以确保不会丢失任何信息。
英文:
I am trying to replace API Data with "All" in Emp_Id field in data in json. And then make rows with every data of API.
I tried in ecmascript but I need in Java as this map function is giving error in nifi.
API DATA: I have stored this data in "Response" attribute in ExtractText in Apache Nifi.
response
{
"status": "success",
"data": [[123, 0], [124, 0], [446, 0], [620, 0], [470 ,1]]
};
jsonData
{
"Emp_Id": "All",
"Emp_loc": "523",
"Emp_dept": "Management",
"Emp_sub_dept": "Finance",
"Emp_sub_dept2": "Accountant"
};
Expected Result
[
{
"Emp_Id":"123",
"Emp_loc":"523",
"Emp_dept":"Management",
"Emp_sub_dept":"Finance",
"Emp_sub_dept2":"Accountant"
},
{
"Emp_Id":"124",
"Emp_loc":"523",
"Emp_dept":"Management",
"Emp_sub_dept":"Finance",
"Emp_sub_dept2":"Accountant"
},
{
"Emp_Id":"446",
"Emp_loc":"523",
"Emp_dept":"Management",
"Emp_sub_dept":"Finance",
"Emp_sub_dept2":"Accountant"
},
{
"Emp_Id":"620",
"Emp_loc":"523",
"Emp_dept":"Management",
"Emp_sub_dept":"Finance",
"Emp_sub_dept2":"Accountant"
},
{
"Emp_Id":"470",
"Emp_loc":"523",
"Emp_dept":"Management",
"Emp_sub_dept":"Finance",
"Emp_sub_dept2":"Accountant"
}
]
This is tried in ecmaScript but I want it to be in Java because these functions are not working in executeScript of NIFI and giving error."java.lang.assertionError: geberating bytecode". Or if any other approach for converting this data.
this is the script I tried
var InputStreamCallback = Java.type("org.apache.nifi.processor.io.InputStreamCallback")
var IOUtils = Java.type("org.apache.commons.io.IOUtils");
var OutputStreamCallback = Java.type("org.apache.nifi.processor.io.OutputStreamCallback");
var StandardCharsets = Java.type("java.nio.charset.StandardCharsets");
var Set = Java.type("java.util.HashSet");
var Map = Java.type("java.util.HashMap");
var String = Java.type("java.lang.String");
var flowFile = session.get();
if (flowFile != null) {
var text = ''
session.read(flowFile,
new InputStreamCallback(function (inputStream) {
text = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
}));
var s3Data ={}
var apiResponse={}
var map = new Map();
var s3Data = JSON.parse(flowFile.getAttribute('jsonData'))
var apiResponse = JSON.parse(flowFile.getAttribute('response'))
var result = apiResponse.data.map(([id]) =>
Object.fromEntries(Object.entries(s3Data).map(([k, v]) =>
[k, v === "All" ? id : v]
))
);
flowFile = session.write(flowFile,
new OutputStreamCallback(function(outputStream) {
outputStream.write(JSON.stringify(result).getBytes(StandardCharsets.UTF_8))
})
);
}
I tried with groovy also but I have very less knowledge of Groovy so I couldn't write the proper ExecuteScript.
答案1
得分: 1
你可以尝试将其转换为 JSONObject,然后替换为所需的值。
- 将响应字符串解析为 simple.JSONObject
- 从中获取数据值
- 将其转换为仅包含数据的第一个值的列表
- 遍历列表并替换 jsonData 的 emp_id 为新值。
String response = "{\r\n"
+ " \"status\": \"success\",\r\n"
+ " \"data\": [[123, 0], [124, 0], [446, 0], [620, 0], [470 ,1]]\r\n"
+ "}";
String jsonData = "{\r\n"
+ " \"Emp_Id\": \"All\",\r\n"
+ " \"Emp_loc\": \"523\",\r\n"
+ " \"Emp_dept\": \"Management\",\r\n"
+ " \"Emp_sub_dept\": \"Finance\",\r\n"
+ " \"Emp_sub_dept2\": \"Accountant\"\r\n"
+ "}";
JSONParser parser = new JSONParser();
JSONObject respObj = (JSONObject)parser.parse(response);
List<JSONArray> numberList = (List)respObj.get("data");
List<Long> replacableNumberList = numberList.stream().map(jsonArray -> (Long)jsonArray.get(0))
.collect(Collectors.toList());
List<JSONObject> outputList = new ArrayList<>();
for (Long integer : replacableNumberList) {
//if parsing before loop then dont forget to create new object before adding in the list
JSONObject jsonObj = (JSONObject)parser.parse(jsonData);
jsonObj.put("Emp_Id", integer);
outputList.add(jsonObj);
}
outputList.forEach(System.out::println);
英文:
You can try converting it to JSONObject and then replace it with the desired values.
- Parse response String to simple.JSONObject
- get the data value out of it
- convert it to list of only first value of data.
- loop through the list and replace the jsonData's emp_id with new value.
String response = "{\r\n"
+ " \"status\": \"success\",\r\n"
+ " \"data\": [[123, 0], [124, 0], [446, 0], [620, 0], [470 ,1]]\r\n"
+ "}";
String jsonData = "{\r\n"
+ " \"Emp_Id\": \"All\",\r\n"
+ " \"Emp_loc\": \"523\",\r\n"
+ " \"Emp_dept\": \"Management\",\r\n"
+ " \"Emp_sub_dept\": \"Finance\",\r\n"
+ " \"Emp_sub_dept2\": \"Accountant\"\r\n"
+ "}";
JSONParser parser = new JSONParser();
JSONObject respObj = (JSONObject)parser.parse(response);
List<JSONArray> numberList = (List)respObj.get("data");
List<Long> replacableNumberList = numberList.stream().map(jsonArray -> (Long)jsonArray.get(0))
.collect(Collectors.toList());
List<JSONObject> outputList = new ArrayList<>();
for (Long integer : replacableNumberList) {
//if parsing before loop then dont forget to create new object before adding in the list
JSONObject jsonObj = (JSONObject)parser.parse(jsonData);
jsonObj.put("Emp_Id", integer);
outputList.add(jsonObj);
}
outputList.forEach(System.out::println);
答案2
得分: 0
你可以尝试使用库_Josson & Jossons_来转换和合并这两个数据集。
https://github.com/octomix/josson
反序列化、转换和合并
使用匹配的key
左连接<=<
两个转换后的数据集。
Josson response = Josson.fromJsonString(
"{" +
" \"status\": \"success\"," +
" \"data\": [[123, 0], [124, 0], [446, 0], [617, 1], [620, 0], [470 ,1]]" +
"}");
Josson jsonData = Josson.fromJsonString(
"{" +
" \"Emp_Id\": \"All\"," +
" \"Emp_loc\": \"523\"," +
" \"Emp_dept\": \"Management\"," +
" \"Emp_sub_dept\": \"Finance\"," +
" \"Emp_sub_dept2\": \"Accountant\"" +
"}");
JsonNode node = new Jossons()
.putDataset("response", response)
.putDataset("jsonData", jsonData)
.evaluateQuery("response->data@.[0].map(Emp_Id:?,key:'All'){key} <=< jsonData->field(key:Emp_Id,Emp_Id:){key}");
System.out.println(node.toPrettyString());
输出
[ {
"Emp_Id" : 123,
"key" : "All",
"Emp_loc" : "523",
"Emp_dept" : "Management",
"Emp_sub_dept" : "Finance",
"Emp_sub_dept2" : "Accountant"
}, {
"Emp_Id" : 124,
"key" : "All",
"Emp_loc" : "523",
"Emp_dept" : "Management",
"Emp_sub_dept" : "Finance",
"Emp_sub_dept2" : "Accountant"
}, {
"Emp_Id" : 446,
"key" : "All",
"Emp_loc" : "523",
"Emp_dept" : "Management",
"Emp_sub_dept" : "Finance",
"Emp_sub_dept2" : "Accountant"
}, {
"Emp_Id" : 617,
"key" : "All",
"Emp_loc" : "523",
"Emp_dept" : "Management",
"Emp_sub_dept" : "Finance",
"Emp_sub_dept2" : "Accountant"
}, {
"Emp_Id" : 620,
"key" : "All",
"Emp_loc" : "523",
"Emp_dept" : "Management",
"Emp_sub_dept" : "Finance",
"Emp_sub_dept2" : "Accountant"
}, {
"Emp_Id" : 470,
"key" : "All",
"Emp_loc" : "523",
"Emp_dept" : "Management",
"Emp_sub_dept" : "Finance",
"Emp_sub_dept2" : "Accountant"
} ]
演示response
的转换
将每个data
元素重定向到单独的分支。对于每个分支,获取第一个数组元素,然后构建一个具有Emp_Id
和key
元素的对象。
JsonNode node = response.getNode("data@.[0].map(Emp_Id:?,key:'All')");
System.out.println(node.toPrettyString());
输出
[ {
"Emp_Id" : 123,
"key" : "All"
}, {
"Emp_Id" : 124,
"key" : "All"
}, {
"Emp_Id" : 446,
"key" : "All"
}, {
"Emp_Id" : 617,
"key" : "All"
}, {
"Emp_Id" : 620,
"key" : "All"
}, {
"Emp_Id" : 470,
"key" : "All"
} ]
演示jsonData
的转换
添加一个具有Emp_Id
值的key
元素,然后删除Emp_Id
。
JsonNode node = jsonData.getNode("field(key:Emp_Id,Emp_Id:)");
System.out.println(node.toPrettyString());
输出
{
"Emp_loc" : "523",
"Emp_dept" : "Management",
"Emp_sub_dept" : "Finance",
"Emp_sub_dept2" : "Accountant",
"key" : "All"
}
英文:
You may try library Josson & Jossons to transform and join the two datasets.
https://github.com/octomix/josson
Deserialize, Transform and Join
Left join <=<
two transformed datasets with matching key
.
Josson response = Josson.fromJsonString(
"{" +
" \"status\": \"success\"," +
" \"data\": [[123, 0], [124, 0], [446, 0], [617, 1], [620, 0], [470 ,1]]" +
"}");
Josson jsonData = Josson.fromJsonString(
"{" +
" \"Emp_Id\": \"All\"," +
" \"Emp_loc\": \"523\"," +
" \"Emp_dept\": \"Management\"," +
" \"Emp_sub_dept\": \"Finance\"," +
" \"Emp_sub_dept2\": \"Accountant\"" +
"}");
JsonNode node = new Jossons()
.putDataset("response", response)
.putDataset("jsonData", jsonData)
.evaluateQuery("response->data@.[0].map(Emp_Id:?,key:'All'){key} <=< jsonData->field(key:Emp_Id,Emp_Id:){key}");
System.out.println(node.toPrettyString());
Output
[ {
"Emp_Id" : 123,
"key" : "All",
"Emp_loc" : "523",
"Emp_dept" : "Management",
"Emp_sub_dept" : "Finance",
"Emp_sub_dept2" : "Accountant"
}, {
"Emp_Id" : 124,
"key" : "All",
"Emp_loc" : "523",
"Emp_dept" : "Management",
"Emp_sub_dept" : "Finance",
"Emp_sub_dept2" : "Accountant"
}, {
"Emp_Id" : 446,
"key" : "All",
"Emp_loc" : "523",
"Emp_dept" : "Management",
"Emp_sub_dept" : "Finance",
"Emp_sub_dept2" : "Accountant"
}, {
"Emp_Id" : 617,
"key" : "All",
"Emp_loc" : "523",
"Emp_dept" : "Management",
"Emp_sub_dept" : "Finance",
"Emp_sub_dept2" : "Accountant"
}, {
"Emp_Id" : 620,
"key" : "All",
"Emp_loc" : "523",
"Emp_dept" : "Management",
"Emp_sub_dept" : "Finance",
"Emp_sub_dept2" : "Accountant"
}, {
"Emp_Id" : 470,
"key" : "All",
"Emp_loc" : "523",
"Emp_dept" : "Management",
"Emp_sub_dept" : "Finance",
"Emp_sub_dept2" : "Accountant"
} ]
Demonstrate the transformation of response
Divert each data
element to separate branches. For each branch, get the first array element and then build an object with element Emp_Id
and key
.
JsonNode node = response.getNode("data@.[0].map(Emp_Id:?,key:'All')");
System.out.println(node.toPrettyString());
Output
[ {
"Emp_Id" : 123,
"key" : "All"
}, {
"Emp_Id" : 124,
"key" : "All"
}, {
"Emp_Id" : 446,
"key" : "All"
}, {
"Emp_Id" : 617,
"key" : "All"
}, {
"Emp_Id" : 620,
"key" : "All"
}, {
"Emp_Id" : 470,
"key" : "All"
} ]
Demonstrate the transformation of jsonData
Add an element key
with the value of Emp_Id
and then remove Emp_Id
.
JsonNode node = jsonData.getNode("field(key:Emp_Id,Emp_Id:)");
System.out.println(node.toPrettyString());
Output
{
"Emp_loc" : "523",
"Emp_dept" : "Management",
"Emp_sub_dept" : "Finance",
"Emp_sub_dept2" : "Accountant",
"key" : "All"
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论