'Get array as result of ScriptEngine.eval()
I'm trying to use javax.script.ScriptEngine to eval()
some JS scripts.
How can I know if the result after eval()
which is of type Object
is an array? And if so, how can I cast it?
Right now, to know if the object is of type Number or of type String i use instanceof
. And when the result of the script is an array, if I print with System.out.println()
the object returned it simply prints [object Array]
.
Solution 1:[1]
As you noticed, it's not java array but a javascript array, if you print the class of the return object, you probably will find it's "ScriptObjectMirror". I have a work around for this which is toString the array in another your script variable, then get the value of that (see below example). I believe there is a better way to resolve this array issue, waiting the good answer too.
engine.eval("var fruits = [\"Banana\", \"Orange\", \"Apple\", \"Mango\"]; var d = fruits.toString();");
System.out.println(engine.get("fruits").getClass());
System.out.println(engine.get("d").getClass());
System.out.println(engine.get("d"));
Solution 2:[2]
In my case modifying the script to make it return list does the trick:
private String arrayToList() {
if (javascript.startsWith("[") && javascript.endsWith("]"))
javascript = "java.util.Arrays.asList(" + javascript + ")";
return javascript;
}
But of course it handles only the case where array results from using brackets, for example:
["entry1", "entry2", settings.getMainUserEmail(), loginEmail]
Anyway the bottom line is that you need to return a List
instead of array. Then you can also use instanceof
.
Solution 3:[3]
How can I know if the result after eval() which is of type Object is an array?
Use instanceof
:
if(result instanceof Object[]){
//your code
}
And if so, how can I cast it?
if(result instanceof Object[]){
Object[] array = (Object[])result;
for(Object o : array) {
//your code
}
}
Solution 4:[4]
final ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("JavaScript");
scriptEngine.eval("count = ['one', 'two', 'three'];");
scriptEngine.eval("className = count.constructor.name;");
final String className = (String) scriptEngine.get("className");
switch(className) {
case "Array":
scriptEngine.eval("json= JSON.stringify(count);");
final String json = (String) scriptEngine.get("json");
final ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
final String[] readValue = mapper.readValue(json, String[].class);
break;
case "Number":
...
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | RedRam |
Solution 2 | |
Solution 3 | free6om |
Solution 4 | Oleksandr Potomkin |