tags:

views:

32607

answers:

16

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?

+12  A: 

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).

Matt Solnit
I second that, Jackson is a wonderful piece of work- much more efficient.
Robert Munteanu
Just curious - why the downvote? Does someone have different (i.e. negative) feedback about Jackson?
Matt Solnit
I tried Jackson when I was doing interoperability between .NET and Java and dates was a mess for me. I don't understand why it's done the way it's done in Jackson. The idea behind JSON is that I should just be able to shuffle data around, I don't have to care about date formats, timezones and all that crap. When I was sending data back and forth between js and c# I had zero problems whatsoever.
Anders Rune Jensen
Hi Anders! JSON does not have a Date type (just strings, numbers, booleans), and each lib therefore has to define its own convention. That can lead to interoperability problems, esp. since default serializations for different languages are different.
StaxMan
One thing that might be interesting wrt Jackson is the performance aspect (Jackson is specifically designed as a very high performance JSON package), see [http://code.google.com/p/thrift-protobuf-compare/wiki/Benchmarking] and [http://www.cowtowncoder.com/blog/archives/2009/09/entry_326.html]
StaxMan
I've just ran into some problems with Jackson, Hibernate and Spring, however, I don't know if this issue is related to Jackson or Spring or Hibernate ... see http://stackoverflow.com/questions/3325387/infinite-recursion-with-jackson-json-and-hibernate-jpa-issue
+13  A: 

I can recommend http://json-lib.sourceforge.net/. We have used it in few projects without problems.

kolec
dfrankow
+6  A: 

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));
Gennady Shumakher
JAXB 2.0 also has support for JSON serialization using Jettison
Mark Renouf
Actually, any XML package that can use Stax API can use Jettison -- JAXB does, so there's no extra work involved (same is mostly true for XStream too, although it may have some additional support).
StaxMan
wwerner
+4  A: 

I've used JSON Tools library and it works well.

carson
+2  A: 

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;
    }
Software Monkey
`crtmbrcbk.invoke(crtprm,psr,tgt,nam,psr.getMemberValue());` What are you, Polish? :) Joking, of course.
Esko
+4  A: 

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.

LeedsSideStreets
I like FlexJSON as well and even modified it to be compatible with Microsoft's JSON serializer really easily.
Chad Grant
+32  A: 

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.

sroebuck
+1. Gson is great. Here's an use example: http://stackoverflow.com/questions/1688099/converting-json-to-java/1688182#1688182
BalusC
This is the solution I went with in the end, and months later I'm very happy with my decision.
sanity
The problem with Gson (at least in versions up to 1.4) is that it is not able to handle circular references. This is very common in some scenarios (JPA/JDO objects being serialized to JSON...)
Guido
Most java json libs do not deal with cyclic deps -- that's more domain of object serialization frameworks. FWIW, XStream with Badgerfish (jettison) does handle them (since it's full object-serialization framework, although resulting json looks ugly, as its xml based, just converts to json via badgerfish)
StaxMan
GSon uses the same design protocol JSON.org went with when developing `JSONObject` and `JSONArray`.
The Elite Gentleman
Design protocol meaning... ? Similar API, or something? I don't see much similarities between the two (which I think is good thing for GSON)
StaxMan
+34  A: 
Piko
Great comparison.
Elliot Vargas
+1 Good of you to point out the relative strengths.
+4  A: 

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.

inder
And yet another example is here: http://stackoverflow.com/questions/2496494/library-to-encode-decode-from-json-to-java-util-map/2496528#2496528
dma_k
Any plans to support circular dependencies in the near future?
Bytecode Ninja
+4  A: 

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();
  }
Nicholas Key
Hi, based on ur experience, is the GSON support JDK1.4 by any chance? I can't find the documentation re the JDK it supports. Thanks.
Nordin
A: 

I've used Jettison and it works well.

adrian.tarau
+4  A: 

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.

Aleksandar Totic
A: 

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();

Sam
A: 

give javajson a try. i wrote it and would definitely love some feedback: https://sourceforge.net/projects/javajson/

miguel
A: 

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!

Thiago Diniz
+1  A: 

I read a review of a few JSON libraries here: Review

Anand