use*_*898 14 javascript arrays scala nashorn
如何将JS数组转换为本机数组?在Rhino转换看起来像(Scala代码):
val eng = (new javax.script.ScriptEngineManager).getEngineByName("JavaScript")
val obj = eng.eval("[1,2,3,4]")
val arr = obj.asInstanceOf[sun.org.mozilla.javascript.internal.NativeArray]
Run Code Online (Sandbox Code Playgroud)
在Nashorn NativeArray缺席,我找不到任何关于转换的文档.
Att*_*edi 16
从Java(和Scala),您还可以convert
在jdk.nashorn.api.scripting.ScriptUtils
类上调用方法.例如来自Java:
import jdk.nashorn.api.scripting.ScriptUtils;
...
int[] iarr = (int[])ScriptUtils.convert(arr, int[].class)
Run Code Online (Sandbox Code Playgroud)
我的Scala不太流利,但我相信相当于:
val iarr = ScriptUtils.convert(arr, Array[Int]).asInstanceOf(Array[Int])
Run Code Online (Sandbox Code Playgroud)
给定一个JavaScript数组,您可以使用oracle nashorn引擎中的Java.to()方法将其转换为Java数组,该引擎可在jdk 8中使用
例
var data = [1,2,3,4,5,6];
var JavaArray = Java.to(data,"int []");
print(JavaArray [0] + JavaArray 1 + JavaArray [2]);
我找到了适用于Rhino和Nashorn的解决方案.
第一个问题,脚本编写者不得处理Java Objects!
这导致了一个只使用Java的解决方案.
其次它必须适用于Java 8和以前的版本!
final ScriptEngineManager manager = new ScriptEngineManager();
final ScriptEngine engine = manager.getEngineByName("JavaScript");
try {
Object result = convert(engine.eval("(function() {return ['a', 'b'];})()"));
log.debug("Result: {}", result);
result = convert(engine.eval("(function() {return [3, 7.75];})()"));
log.debug("Result: {}", result);
result = convert(engine.eval("(function() {return 'Test';})()"));
log.debug("Result: {}", result);
result = convert(engine.eval("(function() {return 7.75;})()"));
log.debug("Result: {}", result);
result = convert(engine.eval("(function() {return false;})()"));
log.debug("Result: {}", result);
} catch (final ScriptException e) {
e.printStackTrace();
}
private static Object convert(final Object obj) {
log.debug("JAVASCRIPT OBJECT: {}", obj.getClass());
if (obj instanceof Bindings) {
try {
final Class<?> cls = Class.forName("jdk.nashorn.api.scripting.ScriptObjectMirror");
log.debug("Nashorn detected");
if (cls.isAssignableFrom(obj.getClass())) {
final Method isArray = cls.getMethod("isArray");
final Object result = isArray.invoke(obj);
if (result != null && result.equals(true)) {
final Method values = cls.getMethod("values");
final Object vals = values.invoke(obj);
if (vals instanceof Collection<?>) {
final Collection<?> coll = (Collection<?>) vals;
return coll.toArray(new Object[0]);
}
}
}
} catch (ClassNotFoundException | NoSuchMethodException | SecurityException
| IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {}
}
if (obj instanceof List<?>) {
final List<?> list = (List<?>) obj;
return list.toArray(new Object[0]);
}
return obj;
}
Run Code Online (Sandbox Code Playgroud)
Rhino提供的数组为sun.org.mozilla.javascript.internal.NativeArray类,它实现了java.util.List接口,易于处理
13:48:42.400 [main] DEBUG de.test.Tester - JAVASCRIPT OBJECT: class sun.org.mozilla.javascript.internal.NativeArray
13:48:42.405 [main] DEBUG de.test.Tester - Result: [a, b]
13:48:42.407 [main] DEBUG de.test.Tester - JAVASCRIPT OBJECT: class sun.org.mozilla.javascript.internal.NativeArray
13:48:42.407 [main] DEBUG de.test.Tester - Result: [3.0, 7.75]
13:48:42.410 [main] DEBUG de.test.Tester - JAVASCRIPT OBJECT: class java.lang.String
13:48:42.410 [main] DEBUG de.test.Tester - Result: Test
13:48:42.412 [main] DEBUG de.test.Tester - JAVASCRIPT OBJECT: class java.lang.Double
13:48:42.412 [main] DEBUG de.test.Tester - Result: 7.75
13:48:42.414 [main] DEBUG de.test.Tester - JAVASCRIPT OBJECT: class java.lang.Boolean
13:48:42.415 [main] DEBUG de.test.Tester - Result: false
Run Code Online (Sandbox Code Playgroud)
Nashorn将JavaScript数组作为jdk.nashorn.api.scripting.ScriptObjectMirror返回,遗憾的是它没有实现List接口.
我用反射解决了它,我想知道Oracle为什么要做出这么大的改变.
13:51:02.488 [main] DEBUG de.test.Tester - JAVASCRIPT OBJECT: class jdk.nashorn.api.scripting.ScriptObjectMirror
13:51:02.495 [main] DEBUG de.test.Tester - Nashorn detected
13:51:02.497 [main] DEBUG de.test.Tester - Result: [a, b]
13:51:02.503 [main] DEBUG de.test.Tester - JAVASCRIPT OBJECT: class jdk.nashorn.api.scripting.ScriptObjectMirror
13:51:02.503 [main] DEBUG de.test.Tester - Nashorn detected
13:51:02.503 [main] DEBUG de.test.Tester - Result: [3.0, 7.75]
13:51:02.509 [main] DEBUG de.test.Tester - JAVASCRIPT OBJECT: class java.lang.String
13:51:02.509 [main] DEBUG de.test.Tester - Result: Test
13:51:02.513 [main] DEBUG de.test.Tester - JAVASCRIPT OBJECT: class java.lang.Double
13:51:02.513 [main] DEBUG de.test.Tester - Result: 7.75
13:51:02.520 [main] DEBUG de.test.Tester - JAVASCRIPT OBJECT: class java.lang.Boolean
13:51:02.520 [main] DEBUG de.test.Tester - Result: false
Run Code Online (Sandbox Code Playgroud)
解决办法是用Java.to函数来做转换:
engine.eval("Java.to(" + script + ",'byte[]')").asInstanceOf[Array[Byte]]
engine.eval("Java.to(" + name + ",'java.lang.String[]')").asInstanceOf[Array[String]]
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
14617 次 |
最近记录: |