Reputation: 504
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.
Upvotes: 3
Views: 18728
Reputation: 1527
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"
} ]
}
Upvotes: 4
Reputation: 5185
Java doesn't have great templating built in.
But if you want to do a quick an dirty JSON template where you can replace a few values -- especially without all that ugly quote escaping:
{"key":"value"}
You can use single quotes and string replace:
{'key':'VALUE'}.replace("'", """).replace("VALUE", 42)
A few caveats:
This will break if any existing keys or values have single quotes (like O'malley).
It won't replace strings with numbers, boolean, or null
It can't -- by itself -- insert nested arrays or objects (e.g. [] {}) other than as strings.
But with a little bit of of extra work, you can accomplish the 80/20 rule. After that point you'd probably want to look into parsing or generating -- but by then you're not looking for a quick template.
Upvotes: 0
Reputation: 11
Your job is to output multilevel JSON data as multiple JSON formats. JSONPath can do this but the process is a hassle.
A simple alternative is to use SPL. SPL is a Java open-source package. You just need three lines of code to get the job done:
SPL offers JDBC driver to be invoked by Java. Just store the above SPL script as jsonparse.splx and invoke it in a Java application as you call a stored procedure:
…
Class.forName("com.esproc.jdbc.InternalDriver");
con= DriverManager.getConnection("jdbc:esproc:local://");
st = con.prepareCall("call jsonparse()");
st.execute();
…
Upvotes: 0
Reputation: 109
I push full worked example in java into GIT with libs (lombok and jackson) Template json mapped to object and object to json with different clients.
Upvotes: 0
Reputation: 3080
You can use Jackson to serialize and deserialize json. I suggest you to create seperate classes which represents your client data.
I show you an example of how you can deserialize your data and map it to your client json.
You can generate corresponding classes for client 2 with getting some help from http://www.jsonschema2pojo.org/ for mapping json to pojo.
Here is the code :
public class Main {
public static void main(String[] args) throws ParseException, ParserConfigurationException, IOException, SAXException {
ObjectMapper mapper = new ObjectMapper();
Root root = mapper.readValue(new File("test.json"), Root.class);
Client1 c1 = new Client1();
PersonalInfo personalInfo1 = new PersonalInfo();
personalInfo1.setAge(root.getAge());
personalInfo1.setFriendsNames(root.getFriends());
personalInfo1.setName(root.getName());
EducationalInfo educationalInfo1 = new EducationalInfo();
educationalInfo1.setCollege(root.getEducation().getCollege());
educationalInfo1.setGrade(root.getEducation().getGrade());
educationalInfo1.setStudy(root.getEducation().getStudy());
c1.setPersonalInfo(personalInfo1);
c1.setEducationalInfo(educationalInfo1);
mapper.writeValue(new File("client1.json"), c1);
}
}
Inside test.json file :
{
"name": "XYZ",
"age": 24,
"education": {
"college": "ppppp",
"study": "b.tech",
"grade": 6.8
},
"friends": [
"kkkk",
"bbbbbbbbbbb",
"jjjjjj"
],
"dob": "01-08-1990"
}
Inside client1.json file :
{
"personalInfo": {
"name": "XYZ",
"age": 24,
"friendsNames": [
"kkkk",
"bbbbbbbbbbb",
"jjjjjj"
]
},
"educationalInfo": {
"college": "ppppp",
"study": "b.tech",
"grade": 6.8
}
}
Here is the classes which represents your json data:
class Education {
private String college;
private String study;
private float grade;
public String getCollege() {
return college;
}
public void setCollege(String college) {
this.college = college;
}
public String getStudy() {
return study;
}
public void setStudy(String study) {
this.study = study;
}
public float getGrade() {
return grade;
}
public void setGrade(float grade) {
this.grade = grade;
}
}
// root of your base json data
class Root {
private String name;
private int age;
private Education education;
private List<String> friends;
private String dob;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Education getEducation() {
return education;
}
public void setEducation(Education education) {
this.education = education;
}
public List<String> getFriends() {
return friends;
}
public void setFriends(List<String> friends) {
this.friends = friends;
}
public String getDob() {
return dob;
}
public void setDob(String dob) {
this.dob = dob;
}
}
class EducationalInfo {
private String college;
private String study;
private float grade;
public String getCollege() {
return college;
}
public void setCollege(String college) {
this.college = college;
}
public String getStudy() {
return study;
}
public void setStudy(String study) {
this.study = study;
}
public float getGrade() {
return grade;
}
public void setGrade(float grade) {
this.grade = grade;
}
}
// class which represents client 1 json data
class Client1 {
private PersonalInfo personalInfo;
private EducationalInfo educationalInfo;
public PersonalInfo getPersonalInfo() {
return personalInfo;
}
public void setPersonalInfo(PersonalInfo personalInfo) {
this.personalInfo = personalInfo;
}
public EducationalInfo getEducationalInfo() {
return educationalInfo;
}
public void setEducationalInfo(EducationalInfo educationalInfo) {
this.educationalInfo = educationalInfo;
}
}
class PersonalInfo {
private String name;
private int age;
private List<String> friendsNames = null;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public List<String> getFriendsNames() {
return friendsNames;
}
public void setFriendsNames(List<String> friendsNames) {
this.friendsNames = friendsNames;
}
}
Upvotes: 3
Reputation: 64
What about converting it to XML then create some XSLT? it might be much readable and cleaner.
Upvotes: 0