Skip to content

Instantly share code, notes, and snippets.

@ledoyen
Last active September 6, 2017 23:11
Show Gist options
  • Save ledoyen/6f4af46f62798980af7e6a2a9ce67ee1 to your computer and use it in GitHub Desktop.
Save ledoyen/6f4af46f62798980af7e6a2a9ce67ee1 to your computer and use it in GitHub Desktop.
Evaluate Javascript functions on JSON data in Java

Java8 is required.

With a method defined as:

private Object evaluate(String jsonDocument, String javascriptFunction) {
    ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
    try {
        String script = "var fun = function(document) {\n" +
                "    return JSON.parse(document)." + javascriptFunction + ";\n" +
                "};";
        System.out.println(script); // debug
        engine.eval(script);
        Invocable invocable = (Invocable) engine;

        return invocable.invokeFunction("fun", jsonDocument);
    } catch (ScriptException | NoSuchMethodException e) {
        throw new RuntimeException(e);
    }
}

It is simple to access and manipulate nested properties with a Javascript expression:

String document = new Scanner(this.getClass().getClassLoader().getResourceAsStream("sample.json"), "UTF-8").useDelimiter("\\A").next();

Object result = evaluate(document, "menu.id");
// String[file]

// Javascript functions are available
result = evaluate(document, "menu.popup.menuitem.map(function (item) {return item.value;})");
// ScriptObjectMirror(Array)[New, Open, Close]

// Nashorn Function Literals
result = evaluate(document, "menu.popup.menuitem.map(function (item) item.value)");
// ScriptObjectMirror(Array)[New, Open, Close]
{"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}
]
}
}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment