-
Notifications
You must be signed in to change notification settings - Fork 102
Slicing and Dicing JSON and Java with Boon or how to customize JSON stream without having 20 Java DTO objects
If you have 75 annotations in a Java class and 25 more in the REST handler than you are doing it 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 50 DTO to match each use case or view.
I could not handle writing 50 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:
##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. Different use cases use different parts of the stream, perhaps the JSON stream even gets put onto a bus and many end points grab it and use different parts of the stream.
public static class TeamRoster {
Set<String> teamNames;
@Override
public String toString() {
return "TeamRoster{" +
"teamNames=" + teamNames +
'}';
}
}
public static class TeamInfo {
TeamRoster teamRoster;
@Override
public String toString() {
return "TeamInfo{" +
"teamRoster=" + teamRoster +
'}';
}
}
In this example we will read the JSON with Boon from the classpath or file system with jsonResource (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.
puts("Team Roster", atIndex(jsonObject, "teamInfo.teamRoster"));
puts("Team Roster", atIndex(jsonObject, "teamInfo.teamRoster"));
puts("Team Names", atIndex(jsonObject, "teamInfo.teamRoster.teamNames"));
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?
TeamInfo teamInfo = 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?
TeamRoster teamRoster = fromMap((Map<String, Object>) atIndex(jsonObject, "teamInfo.teamRoster"), TeamRoster.class);
/*
*/
package com.examples;
import org.boon.Boon;
import org.boon.IO;
import org.boon.json.JsonFactory;
import org.boon.json.JsonParserAndMapper;
import org.boon.json.JsonParserFactory;
import org.boon.json.ObjectMapper;
import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.boon.Boon.atIndex;
import static org.boon.Boon.puts;
import static org.boon.Maps.fromMap;
import static org.boon.Sets.set;
/**
* Created by Richard on 5/6/14.
*/
public class PartialDataTreeExample {
public static class TeamRoster {
Set<String> teamNames;
@Override
public String toString() {
return "TeamRoster{" +
"teamNames=" + teamNames +
'}';
}
}
public static class TeamInfo {
TeamRoster teamRoster;
@Override
public String toString() {
return "TeamInfo{" +
"teamRoster=" + teamRoster +
'}';
}
}
public static void main (String... args) {
File file = new File(".", "src/test/resources/teams.json");
String path = file.getAbsolutePath().toString();
puts ("PATH", path);
puts ("CONTENTS of PATH", IO.read(path));
/* Jackson style interface. */
ObjectMapper mapper = JsonFactory.create();
Object jsonObject = 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). */
JsonParserAndMapper boonMapper = new JsonParserFactory().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);
TeamInfo teamInfo = fromMap((Map<String, Object>) atIndex(jsonObject, "teamInfo"), TeamInfo.class);
puts(teamInfo);
TeamRoster teamRoster = fromMap((Map<String, Object>) atIndex(jsonObject, "teamInfo.teamRoster"), TeamRoster.class);
puts(teamRoster);
}
}
YourKit supports Boon open source project with its full-featured Java Profiler. YourKit, LLC is the creator of innovative and intelligent tools for profiling Java and .NET applications. Take a look at YourKit's leading software products: YourKit Java Profiler and YourKit .Net profiler.