你如何在Java中替换JSON数据中的值?

huangapple go评论67阅读模式
英文:

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,然后替换为所需的值。

  1. 将响应字符串解析为 simple.JSONObject
  2. 从中获取数据值
  3. 将其转换为仅包含数据的第一个值的列表
  4. 遍历列表并替换 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.

  1. Parse response String to simple.JSONObject
  2. get the data value out of it
  3. convert it to list of only first value of data.
  4. 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_Idkey元素的对象。

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 &lt;=&lt; two transformed datasets with matching key.

Josson response = Josson.fromJsonString(
&quot;{&quot; +
&quot;    \&quot;status\&quot;: \&quot;success\&quot;,&quot; +
&quot;    \&quot;data\&quot;: [[123, 0], [124, 0], [446, 0], [617, 1], [620, 0], [470 ,1]]&quot; +
&quot;}&quot;);
Josson jsonData = Josson.fromJsonString(
&quot;{&quot; +
&quot;    \&quot;Emp_Id\&quot;: \&quot;All\&quot;,&quot; +
&quot;    \&quot;Emp_loc\&quot;: \&quot;523\&quot;,&quot; +
&quot;    \&quot;Emp_dept\&quot;: \&quot;Management\&quot;,&quot; +
&quot;    \&quot;Emp_sub_dept\&quot;: \&quot;Finance\&quot;,&quot; +
&quot;    \&quot;Emp_sub_dept2\&quot;: \&quot;Accountant\&quot;&quot; +
&quot;}&quot;);
JsonNode node = new Jossons()
.putDataset(&quot;response&quot;, response)
.putDataset(&quot;jsonData&quot;, jsonData)
.evaluateQuery(&quot;response-&gt;data@.[0].map(Emp_Id:?,key:&#39;All&#39;){key} &lt;=&lt; jsonData-&gt;field(key:Emp_Id,Emp_Id:){key}&quot;);
System.out.println(node.toPrettyString());

Output

[ {
&quot;Emp_Id&quot; : 123,
&quot;key&quot; : &quot;All&quot;,
&quot;Emp_loc&quot; : &quot;523&quot;,
&quot;Emp_dept&quot; : &quot;Management&quot;,
&quot;Emp_sub_dept&quot; : &quot;Finance&quot;,
&quot;Emp_sub_dept2&quot; : &quot;Accountant&quot;
}, {
&quot;Emp_Id&quot; : 124,
&quot;key&quot; : &quot;All&quot;,
&quot;Emp_loc&quot; : &quot;523&quot;,
&quot;Emp_dept&quot; : &quot;Management&quot;,
&quot;Emp_sub_dept&quot; : &quot;Finance&quot;,
&quot;Emp_sub_dept2&quot; : &quot;Accountant&quot;
}, {
&quot;Emp_Id&quot; : 446,
&quot;key&quot; : &quot;All&quot;,
&quot;Emp_loc&quot; : &quot;523&quot;,
&quot;Emp_dept&quot; : &quot;Management&quot;,
&quot;Emp_sub_dept&quot; : &quot;Finance&quot;,
&quot;Emp_sub_dept2&quot; : &quot;Accountant&quot;
}, {
&quot;Emp_Id&quot; : 617,
&quot;key&quot; : &quot;All&quot;,
&quot;Emp_loc&quot; : &quot;523&quot;,
&quot;Emp_dept&quot; : &quot;Management&quot;,
&quot;Emp_sub_dept&quot; : &quot;Finance&quot;,
&quot;Emp_sub_dept2&quot; : &quot;Accountant&quot;
}, {
&quot;Emp_Id&quot; : 620,
&quot;key&quot; : &quot;All&quot;,
&quot;Emp_loc&quot; : &quot;523&quot;,
&quot;Emp_dept&quot; : &quot;Management&quot;,
&quot;Emp_sub_dept&quot; : &quot;Finance&quot;,
&quot;Emp_sub_dept2&quot; : &quot;Accountant&quot;
}, {
&quot;Emp_Id&quot; : 470,
&quot;key&quot; : &quot;All&quot;,
&quot;Emp_loc&quot; : &quot;523&quot;,
&quot;Emp_dept&quot; : &quot;Management&quot;,
&quot;Emp_sub_dept&quot; : &quot;Finance&quot;,
&quot;Emp_sub_dept2&quot; : &quot;Accountant&quot;
} ]

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(&quot;data@.[0].map(Emp_Id:?,key:&#39;All&#39;)&quot;);
System.out.println(node.toPrettyString());

Output

[ {
&quot;Emp_Id&quot; : 123,
&quot;key&quot; : &quot;All&quot;
}, {
&quot;Emp_Id&quot; : 124,
&quot;key&quot; : &quot;All&quot;
}, {
&quot;Emp_Id&quot; : 446,
&quot;key&quot; : &quot;All&quot;
}, {
&quot;Emp_Id&quot; : 617,
&quot;key&quot; : &quot;All&quot;
}, {
&quot;Emp_Id&quot; : 620,
&quot;key&quot; : &quot;All&quot;
}, {
&quot;Emp_Id&quot; : 470,
&quot;key&quot; : &quot;All&quot;
} ]

Demonstrate the transformation of jsonData

Add an element key with the value of Emp_Id and then remove Emp_Id.

JsonNode node = jsonData.getNode(&quot;field(key:Emp_Id,Emp_Id:)&quot;);
System.out.println(node.toPrettyString());

Output

{
&quot;Emp_loc&quot; : &quot;523&quot;,
&quot;Emp_dept&quot; : &quot;Management&quot;,
&quot;Emp_sub_dept&quot; : &quot;Finance&quot;,
&quot;Emp_sub_dept2&quot; : &quot;Accountant&quot;,
&quot;key&quot; : &quot;All&quot;
}

huangapple
  • 本文由 发表于 2023年5月29日 18:51:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/76356706.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定