Tuesday, April 7, 2009

JSON Feed using XStream

Let us write a sample code to generate JSON feed for some matches that can be shared across websites. JSON format looks like as mentioned below – It is an array of several matches played. We have to fetch the match detail (recent match detail) every after ‘n’ minute and create an array having all old match details and the recent match detail. Match detail has match id, match play time, prize amount given and players.

{
"matchDetails": [
{
"matchId": 101,
"time": 937858019,
"prizeAmount": 10000,
"players": [
"John",
"Jean",
"Mike"
]
},
{
"matchId": 102,
"time": 937858019,
"prizeAmount": 12000,
"players": [
"Vivian",
"Angela",
"Andrew"
]
}
]
}


I have used Spring Quartz for scheduling job and XStream to convert java object into JSON.

XStream is very powerful library that converts Java Object to XML / JSON and back again.

So, let us start with writing java class MatchDetail that holds match details.

package test;

import java.util.List;

public class MatchDetail {
private int matchId;

private long time;

private int prizeAmount;

private List players;

public int getMatchId() {
return matchId;
}

public void setMatchId(int matchId) {
this.matchId = matchId;
}

public long getTime() {
return time;
}

public void setTime(long time) {
this.time = time;
}

public int getPrizeAmount() {
return prizeAmount;
}

public void setPrizeAmount(int prizeAmount) {
this.prizeAmount = prizeAmount;
}

public List getPlayers() {
return players;
}

public void setPlayers(List players) {
this.players = players;
}

}

This class generates the JSON Feed –

package test;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.json.JsonHierarchicalStreamDriver;
import com.thoughtworks.xstream.io.json.JsonWriter;

public class FeedGenerator {
IMatchService matchService;

public IMatchService getMatchService() {
return matchService;
}

public void setMatchService(IMatchService matchService) {
this.matchService = matchService;
}

public void generateFeed() throws Exception {
// Get the recent match details
MatchDetail detail = getRecentMatchDetail();

// Get the stored feed
List details = getMatchDetails();

// Add the current match detail to the list
details.add(detail);

// Save it back to the disk
storeMatchDetails(details);

// I have to create JSON – format as shown above, so I write the
// following to store match details as JSON.
saveMatchDetailsAsJSON(details);

}

private MatchDetail getRecentMatchDetail() {
return matchService.getRecentMatchDetail();
}

private List getMatchDetails() throws Exception {
XStream xstream = new XStream();

File file = new File("feed.xml");
if (!file.exists()) {
return null;
}

FileReader fr = new FileReader(file);
ObjectInputStream in = xstream.createObjectInputStream(fr);
List wmds = (ArrayList) in.readObject();
in.close();
fr.close();
return wmds;
}

private void storeMatchDetails(List whds) throws Exception {
XStream xstream = new XStream();

File file = new File("feed.xml");
FileWriter fw = new FileWriter(file);
ObjectOutputStream out = xstream.createObjectOutputStream(fw);

out.writeObject(whds);
out.close();
fw.close();
}

private void saveMatchDetailsAsJSON(List whds)
throws Exception {
XStream xstream = new XStream(new JsonHierarchicalStreamDriver() {
public HierarchicalStreamWriter createWriter(Writer writer) {
return new JsonWriter(writer, JsonWriter.DROP_ROOT_MODE);
}
});

xstream.setMode(XStream.NO_REFERENCES);
xstream.alias("matchDetails", List.class);

File file = new File("matchDetails.js");
FileWriter fw = new FileWriter(file);
ObjectOutputStream out = xstream.createObjectOutputStream(fw);

out.writeObject(whds);
out.close();
fw.close();
}

}

I have to use intermediate feed.xml to store match details. I could have used matchDetails.js but after using “DROP_ROOT_MODE”, alias etc (as I need the JSON format as mentioned above) I was not able to convert JSON back to java object.

Libraries Used –

xstream-1.3.1.jar
xpp3_min-1.1.4c.jar
jettison-1.0.1.jar

Next we will discuss Spring Quartz

No comments: