将toString方法暴露给nashorn中的js对象
expose toString method to js objects in nashorn
这个问题可能很愚蠢,但我找不到任何关于它的直接文档,所以它在这里。
我想向JS端公开一个Java"构造函数",当实例化时,它应该创建一个带有"toString"方法的实例
// java class
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import jdk.nashorn.api.scripting.AbstractJSObject;
public class Foo extends AbstractJSObject {
String bar;
public Foo() {
super();
}
public Foo(String b) {
super();
this.bar = b;
}
@Override
public Object newObject(Object... args) {
String bar = null;
if (args[0] != null) bar = args[0].toString();
Foo f = new Foo(bar);
return f;
}
@Override
public String toString() {
return "Foo: " + this.bar;
}
public static void main(String[] args) {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
engine.put("foo", new Foo());
// f.toString however is null
engine.eval("var f = new foo('hi'); f.toString();")
}
}
如果实现JSObject,nashorn将路由所有属性/索引访问,通过getMember、getSlot、setMember、setSlot等JSObject方法进行调用。我稍微修改了您的代码,将"toString"作为Foo对象的属性公开,并使其可编译&可运行代码:
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import jdk.nashorn.api.scripting.AbstractJSObject;
import java.util.function.Supplier;
public class Foo extends AbstractJSObject {
String bar;
public Foo() {
super();
}
public Foo(String b) {
super();
this.bar = b;
}
@Override
public Object newObject(Object... args) {
String bar = null;
if (args[0] != null) bar = args[0].toString();
Foo f = new Foo(bar);
return f;
}
@Override
public Object getMember(String name) {
if (name.equals("toString")) {
// Returning a lambda function as value of this property.
// nashorn code can call lambdas just like script functions!
// You may also choose to return another JSObject that
// returns true in isFunction() method and implements "call"
// as well.
return (Supplier<String>)this::toString;
} else {
// implement other exposed properties here.
return null;
}
}
@Override
public String toString() {
return "Foo: " + this.bar;
}
public static void main(String[] args) throws Exception {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
engine.put("foo", new Foo());
// f.toString() would call getMember("toString") and the
// returning lambda is called!
engine.eval("var f = new foo('hi'); print(f.toString());");
}
}
您可以尝试以下方式:
import javax.script.*;
import jdk.nashorn.api.scripting.AbstractJSObject;
public class Foo extends AbstractJSObject {
String bar;
public Foo() {
super();
}
public Foo(String b) {
super();
this.bar = b;
}
@Override
public Object newObject(Object... args) {
String bar = null;
if (args[0] != null) bar = args[0].toString();
Foo f = new Foo(bar);
return f;
}
@Override
public String toString() {
return "Foo: " + this.bar;
}
public static void main(String[] args) throws ScriptException {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript");
engine.put("foo", new Foo());
Compilable compilable = (Compilable) engine;
Bindings bindings = engine.createBindings();
String script = "function add(op1,op2){return op1+op2} add(a, b)";
CompiledScript jsFunction = compilable.compile(script);
bindings.put("a", 1);bindings.put("b", 2); //put java object into js runtime environment
Object result = jsFunction.eval(bindings);
System.out.println(result);
}
}
相关文章:
- 通过php页面中的js强制下载txt
- 调用php数组中的JS函数
- 如何引用HTML中节点模块中的js文件
- PHP中的JS.警报没有'不要出现
- 压缩静态HTML文件中的JS和CSS
- 将toString方法暴露给nashorn中的js对象
- 从.js文件调用html中的js函数
- cloudant中的JS trim()函数
- 动态(重新)创建iframe内容不会重置Chrome中的JS对象
- 使用HTML标记中的JS变量在Javascript中动态创建HTML
- 基于AJAX的网站中的JS window.location
- 可以't在Wordpress中从HTML中的JS文件调用函数
- 对php文件的Ajax调用返回该文件中的JS代码,而不是执行它
- 存储在 2D 数组中的 js 调用函数
- 点击蓝色按钮(点击vbs中的js按钮)
- View赢得't在页面更改时加载Rails 4应用程序中的JS
- 如何更新charts.JS值字段中的JS变量
- 从html文件中的js中提取链接
- Rails 4.1.1.:lib/assets/javascripts中的JS文件;t负载
- 将jsondecoded字符串中的js-eescaped-char(或hex-char?)转换为php中的html实体