我是 JSR-223 Java 脚本的新手,实际上我是从 MVEL 切换过来的符合标准 Mozilla Rhino JS .我已阅读所有文档,但卡住了。我试过像在教程中那样通过绑定(bind)从脚本中引用一些 Java 对象:
// my object
public class MyBean {
public String getStringValue() { return "abc" };
}
// initialization
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
// add bindings
engine.put("bean", new MyBean());
// evaluate script, output is "abc"
engine.eval("print(bean.stringValue)");
Java 对象作为属性 bean
从脚本中引用。到目前为止,一切都很好。
但我想在脚本中将我的对象引用为this
,我想使用它的属性和方法而不带任何前缀或明确地带有前缀this
。就像这样:
// add bindings
engine.put(....., new MyBean()); // or whatever ???
// evaluate scripts, all have the same output "abc"
engine.eval("print(stringValue)");
engine.eval("print(this.stringValue)");
我知道 JavaScript 中的 this
具有特殊含义(如在 Java 中),但在 MVEL 脚本中可以通过使用自定义 ParserContext
来完成和定制PropertyHandler
.
在 Rhino 中可以实现这样的功能吗?
非常感谢。
最佳答案
我尝试执行 this idea来自 Pointy 的回答(再次感谢),但此解决方法不适用于没有 this
前缀的属性,恕我直言,这似乎是一样的。没有使用来自 Java API 的 Rhino 1.5,而是来自 Mozilla 的原始 Rhino 1.7。测试用例在这里:
import org.junit.Test;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.Wrapper;
public class RhinoTest2 {
private Obj obj = new Obj();
public class Obj {
public String getStringValue() {
return "abc";
}
}
private Object eval(String expression) {
Context cx = Context.enter();
try {
ScriptableObject scope = cx.initStandardObjects();
// convert my "this" instance to JavaScript object
Object jsObj = Context.javaToJS(obj, scope);
// prepare envelope function run()
cx.evaluateString(scope,
String.format("function run() { %s }", expression),
"<func>", 1, null);
// call method run()
Object fObj = scope.get("run", scope);
Function f = (Function) fObj;
Object result = f.call(cx, scope, (Scriptable) jsObj, null);
if (result instanceof Wrapper)
return ((Wrapper) result).unwrap();
return result;
} finally {
Context.exit();
}
}
@Test
public void test() {
// works
eval("return this.getStringValue()");
eval("return this.stringValue");
// doesn't work, throws EcmaError: ReferenceError: "getStringValue" is not defined.
eval("return getStringValue()");
eval("return stringValue");
}
}
为什么 this.getStringValue()/this.stringValue
有效而 getStringValue()/stringValue
无效?有什么地方被忽视了吗?尖尖的?
关于java - Rhino:如何将 Java 对象传递给脚本,其中可以引用为 "this",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6709542/