As you know..

In JS, a JSON Object is represented by a JS object, and in the Java world it's often represented by Map<String, Object>. In JS a JSON array is represented by a JS array, and in the Java world it's often represented by a List<Object>.

I'd love to be able to pass JSON between JS and Java and vice versa with the minimum of performance overhead. This is particularly important in Vert.x as we chuck a lot of JSON around.

Let's say I have a Java interface which expects some JSON:

interface SomeInterface {

    void expectsJSON(Map<String, Object> json);
}

Right now I am converting from JS-->Java as follows.

var someJson = { foo: "bar"};
String encoded = JSON.stringify(someJson);
Map<String, Object> map = SomeJavaJSONLibrary.decode(encoded);
myObject.expectsJSON(map);

As you can see it's pretty clunky. The other direction is equally as clunky. And it's slow as we're encoding/decoding everything via String.

Then I realised that if I pass a JS object directly into the expectsJSON method Nashorn will provide me with a Map<String, Object> that backs the original object. I.e. I can do this:

var someJson = { foo: "bar"};
myObject.expectsJSON(map);

Yay! No encoding overhead. Fast. :)

And it works with nested json:

var someJson = { foo: "bar", nested: { wibble: "blah"}};

Just when I was getting my hopes up that this would be a great super fast way of transferring JSON betwen Java and JS, I tried it with a nest array:

var someJson = { foo: "bar", nestedArray: [123, 456]};

But in Java, map.get("nestedArray") returns a ScriptObjectMirror not a List as I was hoping. :(

So.. passing from JS to Java: JS Object maps to Map, but JS Array maps to ScriptObjectMirror. (Seems a bit asymmetric?).

Any reason why we can't map JS Array to Java list when calling JS->Java? (Perhaps this is related to my previous question backing a JS Array with a List...)

Do you have any other suggestions for transferring JSON between JS and Java without too much encoding overhead?

Thanks again!







Reply via email to