My Use case is I have a json file but I have to share only few of them to client. Ex: Consider the source json file as shown below.
{
"name": "XYZ",
"age": 24,
"education": {
"college": "ppppp",
"study": "b.tech",
"grade": 6.8
},
"friends": ["kkkk",
"bbbbbbbbbbb",
"jjjjjj"],
"dob":"01-08-1990"
}
For client 1 I have to share below output
{
"personalInfo": {
"name": "XYZ",
"age": 24,
"friendsNames": ["kkkk","bbbbbbbbbbb","jjjjjj"]
},
"educationalInfo": {
"college": "ppppp",
"study": "b.tech",
"grade": 6.8
}
}
For client 2 I have to share below output
{
"personalInformation": {
"nameOfEmployee": "XYZ",
"ageOfEmployee": 24
},
"educationalInformation": {
"college": "ppppp",
"study": "b.tech"
}
}
And for other clients also the use case is same, I have to skip some keys and give different names to the keys. How to dynamically do this by some kind of configuration. I used jsonPath to achieve this but removing few keys from json object is difficult. Any suggestions can be appreciated.
Use a JSON Path library, like JayWay.
Then the 2 templates to transform your source JSON would be:
client 1:
{
"personalInfo": {
"name": "$.name",
"age": "$.age",
"friendsNames": "$.friends"
},
"educationalInfo": "$.education"
}
client 2:
{
"personalInformation": {
"nameOfEmployee": "$.name",
"ageOfEmployee": "$.age"
},
"educationalInformation": {
"college": "$.education.college",
"study": "$.education.study"
}
}
What you need to implement is the recursive template traversal via the JayWay's MapFunction
:
{
ReadContext source = JsonPath.parse(...);
MapFunction mapper = mapFunction(source);
WriteContext template1 = JsonPath.parse(...);
WriteContext template2 = JsonPath.parse(...);
String client1 = template1.map("*", mapper).jsonString();
String client2 = template2.map("*", mapper).jsonString();
}
MapFunction mapFunction(ReadContext source) {
return (templateNode, __) -> switch (templateNode) {
case Map map -> recurse(map, mapFunction(source));
case List list -> recurse(list, mapFunction(source));
case String path -> source.read(path);
};
}
<T, R> R recurse(T templateNode, MapFunction mapper) {
return JsonPath.parse(templateNode).map("*", mapper).read("$");
}
Optionally, if you also need to transform each element of a list of variable length, using the same sub-template for each element, extend the case List list
branch of the mapFunction()
to support a template syntax like:
{
"targetProperty": [ "$.source.path.to.an.array", {
... element template ...
} ]
}
E.g. a template like:
{
"friends": [ "$.friends[?(@ =~ /.{5,}/)]", {
"name": "@",
"since": "$.dob"
} ]
}
would result into:
{
"friends": [ {
"name": "bbbbbbbbbbb",
"since": "01-08-1990"
}, {
"name": "jjjjjj",
"since": "01-08-1990"
} ]
}