Get json object in Array based on key and value in Java - 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;
}
}

Related

Google DLP - Can I use a delimiter to instruct DLP infotype detectors to search only inside that for sensitive text?

I have an issue while trying to deidentify some data with DLP using an object mapper to parse the object into string - send it to DLP for deidentification - getting back the deidentified string and using the object mapper to parse the string back to the initial object. Sometimes DLP will return a string that cannot be parsed back to the initial object (it breaks the json format of the object mapper)
I use an objectMapper to parse an Address object to string like this:
Address(
val postal_code: String,
val street: String,
val city: String,
val provence: String
)
and my objectmapper will transform this object into a string eg: "{\"postal_code\":\"123ABC\",\"street\":\"Street Name\",\"city\":\"My City\",\"provence\":\"My Provence\"}" which is sent to DLP and deidentified (using LOCATION or STREET_ADDRESS detectors).
The issue is that my object mapper would expect to take back the deidentified string and parse it back to my Address object using the same json format eg:
"{\"postal_code\":\"LOCATION_TOKEN(10):asdf\",\"street\":\"LOCATION_TOKEN(10):asdf\",\"city\":\"LOCATION_TOKEN(10):asdf\",\"provence\":\"LOCATION_TOKEN(10):asdf\"}"
But there are a lot of times that DLP will return something like
"{"LOCATION_TOKEN(25):asdfasdfasdf)\",\"provence\":\"LOCATION_TOKEN(10):asdf\"}" - basically breaking the json format and i am unable to parse back the string from DLP to my initial object
Is there a way to instruct DLP infotype detectors to keep the json format, or to look for sensitive text only inside \" * \"?
Thanks
There are some options here using a custom regex and a detection ruleset in order to define a boundary on matches.
The general idea is that you require that findings must match both an infoType (e.g. STREET_ADDRESS, LOCATION, PERSON_NAME, etc.) and your custom infoType before reporting as a finding or for redaction. By requiring that both match, you can set bounds on where the infoType can detect.
Here is an example.
{
"item": {
"value": "{\"postal_code\":\"123ABC\",\"street\":\"Street Name\",\"city\":\"My City\",\"provence\":\"My Provence\"}"
},
"inspectConfig": {
"customInfoTypes": [
{
"infoType": {
"name": "CUSTOM_BLOCK"
},
"regex": {
"pattern": "(:\")([^,]*)(\")",
"groupIndexes": [
2
]
},
"exclusionType": "EXCLUSION_TYPE_EXCLUDE"
}
],
"infoTypes": [
{
"name": "EMAIL_ADDRESS"
},
{
"name": "LOCATION"
},
{
"name": "PERSON_NAME"
}
],
"ruleSet": [
{
"infoTypes": [
{
"name": "LOCATION"
}
],
"rules": [
{
"exclusionRule": {
"excludeInfoTypes": {
"infoTypes": [
{
"name": "CUSTOM_BLOCK"
}
]
},
"matchingType": "MATCHING_TYPE_INVERSE_MATCH"
}
}
]
}
]
},
"deidentifyConfig": {
"infoTypeTransformations": {
"transformations": [
{
"primitiveTransformation": {
"replaceWithInfoTypeConfig": {}
}
}
]
}
}
}
Example output:
"item": {
"value": "{\"postal_code\":\"123ABC\",\"street\":\"Street Name\",\"city\":\"My City\",\"provence\":\"My [LOCATION]\"}"
},
By setting "groupIndexes" to 2 we are indicating that we only want the custom infoType to match the middle (or second) regex group and not allow the :" or " to be part of the match. Also, in this example we mark the custom infoType as EXCLUSION_TYPE_EXCLUDE so that it does not report itself:
"exclusionType": "EXCLUSION_TYPE_EXCLUDE"
If you remove this line, anything matching your infoType could also get redacted. This can be useful for testing though - example output:
"item": {
"value": "{\"postal_code\":\"[CUSTOM_BLOCK]\",\"street\":\"[CUSTOM_BLOCK]\",\"city\":\"[CUSTOM_BLOCK]\",\"provence\":\"[CUSTOM_BLOCK][LOCATION]\"}"
},
...
Hope this helps.

Generate models and serializers from JSON with null value and missing attributes?

i am trying to generate a class model from an APIs JSON response (List), i use some service for auto-generation, and everything seems to work fine until the response JSON start returning attributes with a null value and the other thing is that some attributes are missing when i call the APIs. EX:
response JSON:
[
{
"persone": {
"name": "To John",
"age": 15
},
"group": "ipsum"
},
{
"persone": {
"name": "To John",
"age": null
},
"group": "ipsum"
},
{
"persone": {
"name": "To John"
}
}
]
in the above example, the age attribute is null, and the group attribute is missing in the last object of the list.
My question is how do you create an appropriate class model in that case handling the null and the missing attribute?

Is it possible to get the values from Json object with limit

I have a Json object like this in my Postgres DB:
{
"emails": [
{
"email": {
"id": "e8dc927f-679d-496b-85fb-465edf35c676",
"value": "hello#gmail.com"
}
},
{
"email": {
"id": "1b78758a-abc4-46ef-9de9-c999a0c8c418",
"value": "hello1#gmail.com"
}
}
],
"lastName": {
"id": "718109fd-2d00-475a-829a-c8af9a7f0067",
"value": "lastName"
},
"firstName": {
"id": "6c46a5b3-6f89-4692-a214-4943de22018d",
"value": "firstName"
},
}
And so on big json with around 1000 elements, now I want to parse and get the first 500 elements from json and make another json. what I mean by element here is anything which has Id is a element. For example firstName , LastName, email, email are the elements not the emails. I tried Jackson api but couldn't find a way how to count the elements and make a json exactly like above and return. and when I do any modifications in the first 500 elements I should save the Json with edits. Any help is much appreciated. I even tried postgres array_agg(e) function but that is only accepting only array.

How can I cast json recursively using gson.fromjson

Given I have the following json structure:
{
"Role": {
"id": "5",
"name": "bb1",
"description": "desc1",
"PermissionDeck": [
{
"id": "7",
"Permission": [
{
"id": "398"
},
{
"id": "399"
},
{
"id": "400"
},
{
"id": "401"
},
{
"id": "402"
}
],
"Limit": [
{
"id": "4"
},
{
"id": "5"
}
]
}
]
}
}
If I want to cast this into a LinkedTreeMap result so that its content could be a retrieved by:
result.get("Role") returns Map
and
result.get("Role").get("PermissionDeck").size() == 5
and
result.get("Role").get("PermissionDeck").get(0).get("id") == 398
basically makes gson.fromjson recursively go into the structure, and fold any nested structure into LinkedTreeMap until it gets to the most inner layer, which then gets into LinkedTreeMap
Is this possible without writing custom recursive methods?
You can't. The closest you'll get is with JsonObject and using the appropriate getter for each nested member. In other words, your code needs to be explicit about what it expects in the JSON.
For example
JsonObject result = new Gson().fromJson(theJson), JsonObject.class);
System.out.println(result.getAsJsonObject("Role").getAsJsonArray("PermissionDeck").size());
will print 1 since you only have one element in the JSON array named PermissionDeck in the JSON object named Role in the root JSON object.

Ignore Null Value Fields From Rest API Response Java

In my project when i send Rest Response to Advance Rest Client It only shows Fields which Have some values and Ignores(Does not show) fields which have NULL Values or Empty values.
Part Of Code:
Gson gson=new Gson();
// firstResponse is Object which contains the values
String jsonString = gson.toJson(firstResponse);
test.saveJson(jsonString); //OR System.out.println(jsonString);
return Response.ok(firstResponse).build(); // Response to Rest Client
Response sample To return Response.ok(firstResponse).build();
Advance rest client From web project :
{
"Name": "smith",
"Properties": {
"propertyList": [
{
"ID": "072",
"Number": "415151",
"Address": "Somewhere"
},
{
"ID": "151",
"Number": "a800cc79-99d1-42f1-aeb4-808087b12c9b",
"Address": "ninink"
},
{
"ID": "269",
},
],
},
}
Now when i save this as Json String in DB or When i want to Print this to console it also prints the fiels with null or empty values:
{
"Name": "smith",
"Properties": {
"propertyList": [
{
"ID": "072",
"Number": "415151",
"Address": "Somewhere"
},
{
"ID": "151",
"Number": "a800cc79-99d1-42f1-aeb4-808087b12c9b",
"Address": "ninink"
},
{
"ID": "269",
"Number": "",
"Address": ""
},
],
},
"resultList" :[]
}
How can i print or save this JSON string same as response in rest client i.e. i dont want to print null or empty value field i just want to ignore them.
in top og entity class , try with the annotation
#JsonInclude(Include.NON_EMPTY)
this annotation don't show any empty field in your json.
Not giving you a code but here are some pointers for you:
Read the manual: How to handle NULL values
You may need to use a custom exclusion strategy
Also read this Q&A: Gson: How to exclude specific fields from Serialization without annotations

Categories