RSS

JSON to Java with JDK6

28 Dec

JSON to Java with JDK6

There are multiple frameworks for transforming a JSON expression to a Java object tree, but the Java Platform does not come out of the box with some javax.json package (I heard there are plans for that).

Today I will show that you can easily transform a JSON expression to a simple Java object tree (map, arrays, primitive wrappers and string) with Java 6 and no additional framework.

Obviously, it may not be the best way to proceed, specially when it comes to speed, security or java mapping. However this solution is appropriate if those are not a concern and you don’t want to add a dependency to an external library for parsing JSON expressions.

The solution relies on the javax.script package and its Javascript binding. Indeed what’s best than Javascript to parse JavaScript Object Notation ?

The scripting API provides evaluation of any Javascript which is nice, unfortunately native Javascript objects are not usable from Java, but the magic of Javascript will come to the rescue!

Javascript is a dynamic language which allows to modify its meta object protocol (MOP) to add new functions on native Javascript objects, through the concept of prototypes. We can modify each of the base Javascript type’s prototypes to add a toJava function that will return a Java version of the object:

Object.prototype.toJava = function() {
var m = new java.util.HashMap();
for (var key in this)
if (this.hasOwnProperty(key))
m.put(key, this[key].toJava());
return m;
};
Array.prototype.toJava = function() {
var l = this.length;
var a = new java.lang.reflect.Array.newInstance(java.lang.Object, l);
for (var i = 0;i < l;i++)
a[i] = this[i];
return a;
};
String.prototype.toJava = function() {
return new java.lang.String(this);
};
Boolean.prototype.toJava = function() {
return java.lang.Boolean.valueOf(this);
};
Number.prototype.toJava = function() {
return java.lang.Integer(this);
};

view raw json2java.js This Gist brought to you by GitHub.

Now you probably get the idea, each toJava function returns the Java counterpart of the Javascript object. Initially I wanted to iterate the object tree, but extending the types thanks to the prototype is a much better solution.

We also need to add the missing Java part that loads this JS and uses it to create our Java objects. This is trivial to do thanks to the scripting API, here is how to load the Javascript and setup the engine:

String init = read(Tools.class.getResource("json2java.js"));
ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
engine.eval(init);
jsonParser = engine;

view raw setup This Gist brought to you by GitHub.

Now we need to use the engine to convert JSON expressions:

Bindings bindings = new SimpleBindings();
String eval = "var tmp = (" + json + ");var o = new AtomicReference(tmp.toJava());";
jsonParser.eval(eval, bindings);
AtomicReference ret = (AtomicReference)bindings.get("o");
return ret.get();

view raw parse This Gist brought to you by GitHub.

Here there is a little trick: you can remark the usage of AtomicReference and it may look inappropriate since we are not dealing with concurrent programming. The trick is that if we return a String from the engine to Java, the engine will wrap it as a Javascript string and we want to avoid that. The AtomicReference makes the value opaque to Javascript and the Java code will unwrap it.

Those three pieces together makes a lightweight solution to transform JSON expressions to Java objects. There are certainly corner case not handled in this code, but it’s a solid basis to start with, I saved the code in a GitHub gist there.

http://blog.julienviet.com/2011/12/26/json-to-java-with-jdk6/

 
Để lại bình luận

Posted by on Tháng Mười Hai 28, 2011 in Uncategorized

 

Gửi phản hồi

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Log Out / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Log Out / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Log Out / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Log Out / Thay đổi )

Connecting to %s

 
%d bloggers like this: