Quantcast
Channel: Sleepless Dev
Viewing all articles
Browse latest Browse all 217

How to add Java JSON support without having 200 DTO objects or more annotations than code

$
0
0
If you have 75 annotations in a Java class and 25 more in the REST handler to do JSON than you are doing it wrong. If you have 500 DTO objects to manage every use case or every view then you are using JSON wrong.
Boon was invented after looking at what a SaaS company needed, and seeing what frameworks they were currently using. Boon was the reaction to an idea of let's have 500 DTOs to match each use case or view.
I could not handle writing 500 DTO objects for simple things, and I was sick of there being more annotations in my code then code, and class loaders issues, and , and … so Boon.
Let's say you have a large JSON stream / file / REST POST / Websocket call that looks like this (pretend what you see is large):

Sample JSON of teams

{

"teamInfo":{
"teamRoster":{
"teamNames":["duck","chickens","penguins"]
}

}


}
Sometimes you want to create a team info (TeamInfo). Sometimes you want just the list or Set. Sometimes you want just the team roster (TeamRoster). Different use cases use different parts of the JSON stream. Perhaps the JSON stream even gets put onto an event bus and many end points grab it and use different parts of the stream.

It is JSON so you should be able to add properties without breaking older event bus listeners.

Sample classes (DTO or domain objects).

publicstaticclassTeamRoster{
Set<String>teamNames;

@Override
publicStringtoString(){
return"TeamRoster{"+
"teamNames="+teamNames+
'}';
}
}

publicstaticclassTeamInfo{

TeamRosterteamRoster;

@Override
publicStringtoString(){
return"TeamInfo{"+
"teamRoster="+teamRoster+
'}';
}
}

In this example we will read the JSON with Boon from the classpath or file system withjsonResource (full example below).
/* Using Boon style (easy) 2 parser. */
jsonObject=Boon.jsonResource(path);

Now if we just want the team info part of the JSON we do this:
/* Using Boon path. */
puts("teamInfo",atIndex(jsonObject,"teamInfo"));

(puts is like System.out.println but better)
teamInfo{teamRoster={teamNames=[duck,chickens,penguins]}}
atIndex returns the teamInfo map.
You use atIndex to get just the part you care about. We can get the teamInfo, the teamRoster or the teamNames and different use cases (or different listeners on the bus might care about different things) so they can pick and choose what they want and ignore the rest. This is JSON. It is meant to be flexible.

Grabbing just the teamInfo.teamRoster

puts("Team Roster",atIndex(jsonObject,"teamInfo.teamRoster"));

Grabbing just the teamInfo.teamRoster and teamInfo.teamRoster.teamNames

puts("Team Roster",atIndex(jsonObject,"teamInfo.teamRoster"));
puts("Team Names",atIndex(jsonObject,"teamInfo.teamRoster.teamNames"));

output

Team Roster {teamNames=[duck, chickens, penguins]} 
Team Names [duck, chickens, penguins]
How do we convert team names into a Set?
Easy.
List<String>teamNames=(List<String>)atIndex(jsonObject,"teamInfo.teamRoster.teamNames");

puts("Team Names",teamNames);

Set<String>teamNameSet=set(teamNames);

puts("Converted to a set",teamNameSet);
output
Team Names [duck, chickens, penguins] 
Converted to a set [duck, chickens, penguins]
How do we convert a specific path into the TeamInfo domain object without converting the entire JSON stream?

Getting just the TeamInfo from JSON

TeamInfoteamInfo=fromMap((Map<String,Object>)atIndex(jsonObject,"teamInfo"),TeamInfo.class);
puts(teamInfo);

How do we convert a specific path into the TeamRoster domain object without converting the entire JSON stream?

Getting just the TeamRoster from JSON

TeamRosterteamRoster=fromMap((Map<String,Object>)atIndex(jsonObject,"teamInfo.teamRoster"),TeamRoster.class);

Full example

/*
*/

packagecom.examples;

importorg.boon.Boon;
importorg.boon.IO;
importorg.boon.json.JsonFactory;
importorg.boon.json.JsonParserAndMapper;
importorg.boon.json.JsonParserFactory;
importorg.boon.json.ObjectMapper;

importjava.io.File;
importjava.util.List;
importjava.util.Map;
importjava.util.Set;

importstaticorg.boon.Boon.atIndex;
importstaticorg.boon.Boon.puts;
importstaticorg.boon.Maps.fromMap;
importstaticorg.boon.Sets.set;

/**
* Created by Richard on 5/6/14.
*/
publicclassPartialDataTreeExample{


publicstaticclassTeamRoster{
Set<String>teamNames;

@Override
publicStringtoString(){
return"TeamRoster{"+
"teamNames="+teamNames+
'}';
}
}

publicstaticclassTeamInfo{

TeamRosterteamRoster;

@Override
publicStringtoString(){
return"TeamInfo{"+
"teamRoster="+teamRoster+
'}';
}
}

publicstaticvoidmain(String...args){
Filefile=newFile(".","src/test/resources/teams.json");
Stringpath=file.getAbsolutePath().toString();
puts("PATH",path);
puts("CONTENTS of PATH",IO.read(path));

/* Jackson style interface. */
ObjectMappermapper=JsonFactory.create();
ObjectjsonObject=mapper.readValue(file,Object.class);
puts("JSON Object",jsonObject);


/* Using Boon path. */
puts("teamInfo",atIndex(jsonObject,"teamInfo"));
puts("Team Roster",atIndex(jsonObject,"teamInfo.teamRoster"));
puts("Team Names",atIndex(jsonObject,"teamInfo.teamRoster.teamNames"));


/* Using Boon style parser (fast). */
JsonParserAndMapperboonMapper=newJsonParserFactory().create();
jsonObject=boonMapper.parseFile(path);


/* Using Boon path. */
puts("teamInfo",atIndex(jsonObject,"teamInfo"));
puts("Team Roster",atIndex(jsonObject,"teamInfo.teamRoster"));
puts("Team Names",atIndex(jsonObject,"teamInfo.teamRoster.teamNames"));



/* Using Boon style (easy) 2 parser. */
jsonObject=Boon.jsonResource(path);


/* Using Boon path. */
puts("teamInfo",atIndex(jsonObject,"teamInfo"));
puts("Team Roster",atIndex(jsonObject,"teamInfo.teamRoster"));
puts("Team Names",atIndex(jsonObject,"teamInfo.teamRoster.teamNames"));

//There is also a Groovy style and a GSON style.

List<String>teamNames=(List<String>)atIndex(jsonObject,"teamInfo.teamRoster.teamNames");

puts("Team Names",teamNames);

Set<String>teamNameSet=set(teamNames);

puts("Converted to a set",teamNameSet);


TeamInfoteamInfo=fromMap((Map<String,Object>)atIndex(jsonObject,"teamInfo"),TeamInfo.class);
puts(teamInfo);


TeamRosterteamRoster=fromMap((Map<String,Object>)atIndex(jsonObject,"teamInfo.teamRoster"),TeamRoster.class);
puts(teamRoster);

}

}

Viewing all articles
Browse latest Browse all 217

Latest Images

Trending Articles



Latest Images