Can anyone recommend a good Java JSON library (better than the one from http://json.org/)? I've also found JSON-lib, which definitely looks like an improvement, but I'm wondering if there is anything that is even better than that?
I can't truly recommend this, because I've never used it, but Jackson sounds promising. The main reason I mention it is that the author, Tatu Saloranta, has done some really great stuff (including Woodstox, the StAX implementation that I use).
I can recommend http://json-lib.sourceforge.net/. We have used it in few projects without problems.
I have no personal experience with the following approach,but it could make sense to consider:
XStream(xml <-> java data binding) with Jettison driver (xml<->json mapper), more details are available here.
That's from their site:
XStream xstream = new XStream(new JettisonMappedXmlDriver()); xstream.alias("product", Product.class); System.out.println(xstream.toXML(product));
I wrote a JSON "pull-api" parser (3 classes, 18K), which I really like using. I find the pull metaphor much more usable than the event metaphor, and creating a document tree using pull is trivial.
FWIW I didn't much care for the www.json.org parser either. My biggest complaint with the offerings out there is the size of them - we target a download-constrained applet market. I remember lying in bed one night at about 2am wondering "how hard could it be", after a bit I got up and started writing - this tiny parser is the result.
JSON Tools looks good too.
I am going to post the package on my website eventually - I could make the effort and post it by the end of the coming weekend if that time frame suits you? Note that the code is almost entirely self contained; a few minor tweaks will be needed (like changing the JsonException superclass - adding throws clauses if you don't want to use RuntimeException). Comment on this if you would like me to do that.
The following generalized recursive code parses a JSON file into a "DataStruct" - essentially a map of lists (Note that DataStruct and Callback are objects from another package which I won't be publishing with this parser, though I will publish both separately at a later time):
/**
* Parse a generalized data structure from a JSON input stream.
* <p>
* All values are added using the <code>crtmbrcbk</code> callback.
* <p>
* <b><u>Reminder</b></u>
* <p>
* When using a reflected method, don't forget to configure your code obfuscator to retain it in unobfuscated form.
*
* @param psr The parser to use.
* @param tgt Target object to which to add members; if this is null a new object is created using the callback.
* @param maxlvl Maximum level to recursively parse substructures, including arrays (objects at a deeper level are silently ignored).
* @param crtmbrcbk A callback object invoked to create a member value.
* @see #createMemberCallback(Object,String)
*/
static public Object parseObject(JsonParser psr, Object tgt, int maxlvl, Callback crtmbrcbk) {
return _parseObject(psr,tgt,maxlvl,crtmbrcbk,new Object[4],false);
}
static private Object _parseObject(JsonParser psr, Object tgt, int maxlvl, Callback crtmbrcbk, Object[] crtprm, boolean arr) {
int evt; // event code
if(tgt==null) { tgt=crtmbrcbk.invoke(crtprm,psr,null,"",null); }
while((evt=psr.next())!=JsonParser.EVT_INPUT_ENDED && evt!=JsonParser.EVT_OBJECT_ENDED && evt!=JsonParser.EVT_ARRAY_ENDED) {
String nam=psr.getMemberName();
switch(evt) {
case JsonParser.EVT_OBJECT_BEGIN : {
if(nam.length()>0) {
if(maxlvl>1) { _parseObject(psr,crtmbrcbk.invoke(crtprm,psr,tgt,nam,null),(maxlvl-1),crtmbrcbk,crtprm,false); }
else { psr.skipObject(); }
}
else {
_parseObject(psr,tgt,maxlvl,crtmbrcbk,crtprm,false);
}
} break;
case JsonParser.EVT_ARRAY_BEGIN : {
if(!arr) {
_parseObject(psr,tgt,maxlvl,crtmbrcbk,crtprm,true); // first level of any array is added directly to the inherently list-supporting object
}
else {
if(maxlvl>1) { _parseObject(psr,crtmbrcbk.invoke(crtprm,psr,tgt,nam,null),(maxlvl-1),crtmbrcbk,crtprm,true); }
else { psr.skipArray(); }
}
} break;
case JsonParser.EVT_OBJECT_MEMBER : {
crtmbrcbk.invoke(crtprm,psr,tgt,nam,psr.getMemberValue());
} break;
}
}
return tgt;
}
I've been meaning to try Flexjson. It looks like it uses reflection on bean-style properties and uses similar rules as Hibernate/JPA lazy-loading for serialization, so if you give it an object to serialize it will leave out collections (unless you tell it to include them) so you don't end up serializing the entire object graph. The json.org library does pretty well with serializing basic beans with reflection, but doesn't have these advanced features. Might be worth checking out, especially if you use an ORM solution.
I notice that there is also a library called google-gson. I haven't tried it yet. Here's how it describes itself:
Gson is a Java library that can be used to convert Java Objects into its JSON representation. It can also be used to convert a JSON string to an equivalent Java object. Gson can work with arbitrary Java objects including pre-existing objects that you do not have source-code of.
There are a few open-source projects that can convert Java objects to JSON. However, most of them require that you place Java annotations in your classes something that you can not do if you do not have access to the source-code. Most also do not fully support the use of Java Generics. Gson considers both of these as very important design goals.
Gson can also be used to serialize arbitrarily complex objects. Here is how you use it:
Gson gson = new Gson();
String json = gson.toJson(myObject);
Gson will automatically convert collections to JSON arrays. Gson can serialize private fields and automatically ignores transient fields.
While deserializing, Gson can automatically convert JSON arrays to collections or arrays. Gson uses the specified class as the primary specification for deserialization. So, any extra fields available in the JSON stream are ignored. This helps design secure systems that prevent injection attacks.
You can also extend Gson's default serialization and/or deserialization behavior by registering custom type adapters.
For more details: see the user guide at the project: http://code.google.com/p/google-gson/
Disclosure: I am one of the co-authors of Gson.
You may try using GSON. It's downloadable at http://google-gson.googlecode.com/files/google-gson-1.4-release.zip
Quite simple to use actually. I used it to parse JSON results from Yelp and there is a simple example here:
URL URLsource = null;
JsonElement jse = null;
BufferedReader in;
try {
URLsource = new URL("YELP_API_REQUEST");
in = new BufferedReader(new InputStreamReader(URLsource.openStream(), "UTF-8"));
jse = new JsonParser().parse(in);
in.close();
System.out.println(jse.toString());
JsonArray jsa = jse.getAsJsonObject().getAsJsonArray("businesses");
System.out.println(jsa.size());
for (int i= 0; i<jsa.size(); i++ ) {
System.out.println(jsa.get(i));
System.out.println("===========================================================");
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Just went through this exercise. I wanted to represent arbitrary JSON as nearest Java equivalent. For me that is a HashMap/ArrayList Object. json-simple was excellent: tiny, with a simple API that generates HashMap/ArrayList with a single call. It also has extensions for object serialization/deserialization.
I also tried gson: API was very object serialization oriented, and type safe, could not do what I needed simply.
I liked J2J - Json2Java from sourceforge.(http://sourceforge.net/projects/json2java/)
Really easy to map JSON to almost any java object by only annotating the class using JsonElement and then passing the java and class to JsonReader like:
MyClass myclass = (MyClass) new JsonReader(MyClass.class, jsonString).toObject();
give javajson a try. i wrote it and would definitely love some feedback: https://sourceforge.net/projects/javajson/
I was reading articles about the JAX-RS, and i realize that there isn't an onfficial lib for serialize and pojo to json object!