How to extract a particular value from Json Node? - java

Hi I have Input of JsonNode type as follows:
{
"Records": [
{
"EventSource": "aws:sns",
"EventVersion": "1.0",
"EventSubscriptionArn": "arn:aws:sns:us-west-1:270252992114:d1dd43d0-8bf1-496c-bc94-f4e70dec5032",
"Sns": {
"Type": "Notification",
"MessageId": "923d528f-c844-5d49-95de-018f6d583bfd",
"TopicArn": "arn:aws:sns:us-west-1:270252992114:",
"Subject": null,
"Message": "AAAAAQAAAAAAAAABAAAAJGNvbS5hbWF6b24uY3VzdG9tZXJldmVudC5jZXMudGVzdC5OQQAAABDW7HxyIs4PvuXtarSxIxdeAAABALZT+4Yv09z9tK48/miZ6IhjvVCLixiH3GLltCxQzEkNgf9NTD57G744vdnw1D3LxLmxT4i0CCkVJJ5IPaH3Ud5Oy6MKa5wRrldtS6MTDMzKqoPwcdMiLm3AogonUAqyBYrxWt8fHrCYIlggX9EFW9Dk9ugDRrJuhCZqfVnt/wRUyP33DycwRKHBHSxn1XuDi9ZyEeCxrMLn9rGmpVvUQb3mdFReoVDmP4cEWcQEwYxG6/WvyimHGD5JtSxzlCR3rwddu8vXlp9Mq127+scPipAm83IJSw7CS5laZQZAD8qR4WwSfSZw8kq72y/LulhzWj3w7jbtOtmhbdnPyIN+L4I=",
"Timestamp": "2018-02-16T09:22:36.149Z",
"SignatureVersion": "1",
"Signature": "f+23JQ6r9gZL6dRay4wqJHrX5CnB9cSVpPS/zgopPKHFOD5zvEpuTiGfuNf0e2L6/84pm6gK9xCEakzeaWtBAp7J/hFfbKQ2BSJ/GAKX1peG16Q8TS2k0NVxjzG4ImEHxf3i3ODOFJeA7WHxRZiMkNO+79lZDxkkOQdfWR3OEQ1yP8CjE4HLlLoSEUdk170AOw1nty9NZ6FOnsotLf5jce0GrXs1lkn7J/3nv/YlSqdMZEAR4SZDELCH3krQ4mUO7gwUfkDSFXsjWLarTayYl20eH3g/RZLQgPEQGTRBZW5wrknXg1vm4H4ICxxrGJBooAs7BCLkUVT1m4juRrlljA==",
"SigningCertUrl": "https://sns.us-west-1.amazonaws.com/SimpleNotificationService-433026a4050d206028891664da859041.pem",
"UnsubscribeUrl": "https://sns.us-west-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-1:270252992114:",
"MessageAttributes": {}
}
}
]
}
I want to extract value of TopicArn and Message, I tried following code but rawSns is coming as null:
JsonNode rawResource = input.get("Records");
logger.log("rawResource is: " + rawResource);
JsonNode rawSns = rawResource.get("Sns");
Does anyone can help me out in this?

You can use following:
JsonNode rawResource = input.get("Records");
logger.log("rawResource is: " + rawResource);
JsonNode rawSns = rawResource.get(0).get("Sns");
See here for Javadoc

This is precisely what you need.
var jsonObject = JSON.parse('{"Records":[{"EventSource":"aws:sns","EventVersion":"1.0","EventSubscriptionArn":"arn:aws:sns:us-west-1:270252992114:d1dd43d0-8bf1-496c-bc94-f4e70dec5032","Sns":{"Type":"Notification","MessageId":"923d528f-c844-5d49-95de-018f6d583bfd","TopicArn":"arn:aws:sns:us-west-1:270252992114:","Subject":null,"Message":"AAAAAQAAAAAAAAABAAAAJGNvbS5hbWF6b24uY3VzdG9tZXJldmVudC5jZXMudGVzdC5OQQAAABDW7HxyIs4PvuXtarSxIxdeAAABALZT+4Yv09z9tK48/miZ6IhjvVCLixiH3GLltCxQzEkNgf9NTD57G744vdnw1D3LxLmxT4i0CCkVJJ5IPaH3Ud5Oy6MKa5wRrldtS6MTDMzKqoPwcdMiLm3AogonUAqyBYrxWt8fHrCYIlggX9EFW9Dk9ugDRrJuhCZqfVnt/wRUyP33DycwRKHBHSxn1XuDi9ZyEeCxrMLn9rGmpVvUQb3mdFReoVDmP4cEWcQEwYxG6/WvyimHGD5JtSxzlCR3rwddu8vXlp9Mq127+scPipAm83IJSw7CS5laZQZAD8qR4WwSfSZw8kq72y/LulhzWj3w7jbtOtmhbdnPyIN+L4I=","Timestamp":"2018-02-16T09:22:36.149Z","SignatureVersion":"1","Signature":"f+23JQ6r9gZL6dRay4wqJHrX5CnB9cSVpPS/zgopPKHFOD5zvEpuTiGfuNf0e2L6/84pm6gK9xCEakzeaWtBAp7J/hFfbKQ2BSJ/GAKX1peG16Q8TS2k0NVxjzG4ImEHxf3i3ODOFJeA7WHxRZiMkNO+79lZDxkkOQdfWR3OEQ1yP8CjE4HLlLoSEUdk170AOw1nty9NZ6FOnsotLf5jce0GrXs1lkn7J/3nv/YlSqdMZEAR4SZDELCH3krQ4mUO7gwUfkDSFXsjWLarTayYl20eH3g/RZLQgPEQGTRBZW5wrknXg1vm4H4ICxxrGJBooAs7BCLkUVT1m4juRrlljA==","SigningCertUrl":"https://sns.us-west-1.amazonaws.com/SimpleNotificationService-433026a4050d206028891664da859041.pem","UnsubscribeUrl":"https://sns.us-west-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-1:270252992114:","MessageAttributes":{}}}]}');
console.log(((jsonObject["Records"][0])["Sns"])["TopicArn"]);
This online tool can help you understand the structure of your JSON : JSON viewer.

Related

Get json object in Array based on key and value in Java

I have a Json body like the example below. I need to extract the value from a key that has another key with a specific value in an array. I am passing in a JsonNode with everything in the detail component of the message, I can easily extract from each level, however, I'm struggling with the array.
In this case, I need to extract the value of "value" (Police/Fire/Accident Report) from the object in the array which has a key/value pair of "name":"documentTitle". I understand this is a JSONArray, but I can't find a good example that shows me how to extract the values for an object in the array that contains a certain key/value pair, I don't think I can rely on getting the object in position [2] in the array as the same objects may not always be present in the additionalMetadata array.
Sample Json:
"sourceVersion": "1.0",
"eventId": "8d74b892-810a-47c3-882b-6e641fd509eb",
"clientRequestId": "b84f3a7b-03cc-4848-a1e8-3519106c6fcb",
"detail": {
"stack": "corona",
"visibilityIndicator": null,
"documentUid": "b84f3a7b-03cc-4848-a1e8-3519106c6fcb",
"additionalMetadata": [
{
"name": "lastModifiedDate",
"value": "2021-05-21T04:53:53Z"
},
{
"name": "documentName",
"value": "Police/Fire Report, 23850413, 2021-05-20 14:51:23"
},
{
"name": "documentTitle",
"value": "Police/Fire/Accident Report"
},
{
"name": "documentAuthor",
"value": "System Generated"
},
{
"name": "lastModifiedBy",
"value": "System Updated"
},
{
"name": "createdBy",
"value": "System Generated"
},
{
"name": "documentDescription",
"value": "Police/Fire Report received"
},
{
"name": "organizationCode",
"value": "Claims"
}
]
}
}```
Loop through the json array and extract the json object with name documentTitile. From that json object you can get the value
Well, either the JSON framework you're using supports this out of the box (check the documentation) or you could convert it manually to a map:
List<AdditionalMetadataEntry> additionalMetadata;
[...]
Map<String, String> additionalMetadataMap = additionalMetadata.stream().collect(Collectors.toMap(AdditionalMetadataEntry::getName, AdditionalMetadataEntry::getValue));
I was able to figure it out. I created a new node off the existing notificationBody JsonNode, then parsed through the metadata key/value pairs:
String docTitle = "";
JsonNode additionalMetadata = notificationBody.get("detail").get("additionalMetadata");
for (JsonNode node: additionalMetadata) {
String name = node.get("name").asText();
String value = node.get("value").asText();
if(name.equals("documentTitle")){
docTitle = value;
}
}

Adding changes to the JSON structure

I have the following JSON, generated in the Android application:
{
"Details": {
"ClaimDate": "08/10/2019",
"HFCode": "55555"
},
"Items": [
{
"Item": {
"ItemCode": "Y203",
"ItemPrice": "20",
"ItemQuantity": "1"
}
}
],
"Services": [
{
"Service": {
"ServiceCode": "X105",
"ServicePrice": "200",
"ServiceQuantity": "1"
}
}
]
}
On the server side, I need this structure
{
"details": {
"ClaimDate": "08/10/2019",
"HFCode": "55555"
},
"items": [
{
"itemCode": "Y200",
"itemPrice": 0,
"itemQuantity": 0
}
],
"services": [
{
"serviceCode": "X100",
"servicePrice": 0,
"serviceQuantity": 0
}
]
}
Is there a way to customize this on the Android application side?
I try to do it manually, but I can't get a satisfactory result
You can use a transformer function which will take the first json/object as input and returns the second json/object as output. Unfortunately, since your keys and data types are different, standard libraries will not able to do this. If you want to use Jackson or Gson, you will have to play with Custom (De) Serializers.
If you are using Jackson (One of the most popular JSON libraries) and you just want to transform the given JSON string into another one, then you can achieve this by following way:
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(jsonStr);
ObjectNode rootNew = mapper.createObjectNode();
rootNew.put("details", root.get("Details"));
JsonNode itemNode = root.get("Items").get(0).get("Item");
ObjectNode itemsNodeNew = mapper.createObjectNode();
itemsNodeNew.put("itemCode", itemNode.get("ItemCode"));
itemsNodeNew.put("itemPrice", itemNode.get("ItemPrice"));
itemsNodeNew.put("itemQuantity", itemNode.get("ItemQuantity"));
rootNew.put("items", mapper.createArrayNode().add(itemsNodeNew));
JsonNode serviceNode = root.get("Services").get(0).get("Service");
ObjectNode serviceNodeNew = mapper.createObjectNode();
serviceNodeNew.put("serviceCode", serviceNode.get("ServiceCode"));
serviceNodeNew.put("servicePrice", serviceNode.get("ServicePrice"));
serviceNodeNew.put("serviceQuantity", serviceNode.get("ServiceQuantity"));
rootNew.put("services", mapper.createArrayNode().add(serviceNodeNew));
System.out.println(rootNew.toString());
But if you want to convert the JSON string to POJO for further manipulation, you can directly deserialize and serialize it.

Create a brand new type of searchable tree in JSON for Java

I am thinking of a new way to extract data from JSON. The following example is what I want:
Look for a key and value pair and give me that object.
Inside that object, give me the value to this key.
I want to get the power of knighthero in the following JSON, by telling it to find the username knighthero. This is really difficult, and I've tried JSONArray and JSONObject, but can't figure it out. I know the length is 3, but now what?
{
"data": [
{
"power": 75,
"registrant": {
"group": "elf",
"username": "kevin23"
}
},
{
"power": 34,
"registrant": {
"group": "fairy",
"username": "msi56"
}
},
{
"power": 150,
"registrant": {
"group": "orc",
"username": "knighthero"
}
}
]
}
I have tried JsonPath and all I get is [] when I print the string. I have tried JSONArray, but can't figure out how to do it.
With org.json librairy and your json described.
JSONObject jo0 = new JSONObject("{\"data\": ["
+ "{\"power\": 75,"
+ "\"registrant\": {\"group\": \"elf\",\"username\": \"kevin23\"}},"
+ "{\"power\": 34,"
+ "\"registrant\": {\"group\": \"fairy\",\"username\": \"msi56\"}},"
+ "{\"power\": 150,"
+ "\"registrant\": {\"group\": \"orc\",\"username\": \"knighthero\"}}"
+ "]}");
JSONArray ja = jo0.getJSONArray("data");
for(int i=0;i<ja.length();i++){
if(ja.getJSONObject(i).getJSONObject("registrant").getString("username").equals("knighthero")){
System.out.println(ja.getJSONObject(i).getInt("power"));
break;
}
}
EDIT
My bad, I make a mistake, here the good version

How to get count all json nodes using Jackson framework

Here is my user.json
{
"id":1,
"name":{
"first":"Yong",
"last":"Mook Kim"
},
"contact":[
{
"type":"phone/home",
"ref":"111-111-1234"
},
{
"type":"phone/work",
"ref":"222-222-2222"
}
]
},
{
"id":2,
"name":{
"first":"minu",
"last":"Zi Lap"
},
"contact":[
{
"type":"phone/home",
"ref":"333-333-1234"
},
{
"type":"phone/work",
"ref":"444-444-4444"
}
]
}
I would like count how many json object is in there. For example the above json has 2 json object id = 1 and id =2.
//tree model approach
ObjectMapper mapper = new ObjectMapper();
JsonNode rootNode = mapper.readTree(new File("user.json"));
List<JsonNode> listOfNodes = rootNode.findParents("first");
System.out.println(listOfNodes.size());
Giving me size = 1.
Can you please tell me what i am doing wrong?
Thanks
Your java code is correct but your json file is invalid.
Jackson parses only first valid element ("Yong").
To fix this just add [ at the begining and ] at the end of file (make it array).

Insert value into ObjectNode and return JsonNode in Jackson json library

I am trying to insert a value into a json object in the following format and save it to the database.
{
"mainObject": {
"childObject1": {
"validator": {
"dataType": "TEXT",
"regEx": "^[a-zA-Z0-9_]*{3,10}$"
},
"input": "Enter data value here"
},
"childObject2": {
"validator": {
"dataType": "TEXT",
"regEx": "^[a-zA-Z0-9_]*{3,10}$"
},
"input": "Enter data value here"
}
}
}
I need to enter values in the tag where it says input. Something like this:
{
"mainObject": {
"childObject1": {
"validator": {
"dataType": "TEXT",
"regEx": "^[a-zA-Z0-9_]*{3,10}$"
},
"input": "Input 1"
},
"childObject2": {
"validator": {
"dataType": "TEXT",
"regEx": "^[a-zA-Z0-9_]*{3,10}$"
},
"input": "Input 2"
}
}
}
I have tried the following code snippet in java. I am able to insert data into the right node.
String output = "{
\"mainObject\": {
\"childObject1\": {
\"validator\": {
\"dataType\": \"TEXT\",
\"regEx\": \"^[a-zA-Z0-9_]*{3,10}$\"
},
\"input\": \"Enter data value here\"
},
\"childObject2\": {
\"validator\": {
\"dataType\": \"TEXT\",
\"regEx\": \"^[a-zA-Z0-9_]*{3,10}$\"
},
\"input\": \"Enter data value here\"
}
}
}";
ObjectMapper mapper = new ObjectMapper();
JsonNode rootNode = mapper.readTree(output);
ObjectNode newMetadata = (ObjectNode) rootNode.path("mainObject").path("childObject1");
newMetadata.put("inputValue", "Input 1");
My problem is how to update and write this back to the mainObject node. At the moment the child nodes input tag is updated with the value, i want to update the mainobject with this and save to database.
I have already pasted the code that had the answer. I was looking at the wrong node. I mentioned in my previous comment, I didn't really see an option to close the question. To make it clear, the answer was that as soon as I write to the child nodes, the parent node will have the property as well. That is working code which does not really need a fix, as I said I was looking at the wrong node.

Categories