Как добавить методы из класса Java в качестве глобальных функций в Javascript с помощью Rhino?
у меня есть простой класс Java, который имеет несколько методов:
public class Utils {
public void deal(String price, int amount) {
// ....
}
public void bid(String price, int amount) {
// ....
}
public void offer(String price, int amount) {
// ....
}
}
Я хотел бы создать экземпляр этого класса и разрешить коду Javascript вызывать методы напрямую, например:
deal("1.3736", 100000);
bid("1.3735", 500000);
единственный способ, который я мог понять сейчас, это использовать
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
engine.put("utils", new Utils());
и затем использовать utils.deal(...)
в коде Javascript. Я также могу писать функции-оболочки в Javascript для каждого метода, но должен быть более простой способ сделать это автоматически для всех открытые методы класса.
3 ответов
Я не очень знаком с Rhino, но что-то вроде этого должно работать:
for(var fn in utils) {
if(typeof utils[fn] === 'function') {
this[fn] = (function() {
var method = utils[fn];
return function() {
return method.apply(utils,arguments);
};
})();
}
}
просто цикл над свойствами utils
, и для каждого, который является функцией, создайте глобальную функцию, которая вызывает ее.
EDIT: я получил это работает в Заводном скрипте, но я должен был установить utils в привязках, а не на движке, как в вашем коде:
import javax.script.*
class Utils {
void foo(String bar) {
println bar
}
}
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
engine.eval("""
for(var fn in utils) {
if(typeof utils[fn] === 'function') {
this[fn] = (function() {
var method = utils[fn];
return function() {
return method.apply(utils,arguments);
};
})();
}
}
foo('foo'); // prints foo, sure enough
""",new SimpleBindings("utils":new Utils()))
Я не уверен, как это будет работать с помощью API JSR-223, но с API Rhino вы можете создать FunctionObject
С методом, который вы хотите добавить.
Class[] parameters = new Class[] { String.class, Integer.class };
Method dealMethod = Utils.class.getMethod("deal", parameters);
engine.put("deal", new FunctionObject("deal", dealMethod, scope));
документация доступна на https://www.mozilla.org/rhino/apidocs/org/mozilla/javascript/FunctionObject.html.
для доступа к FunctionObject
класс, и я не уверен, как вы получили бы scope
объект с API JSR-223 (хотя, возможно, что null
будет работать).
Это возможно, если вы используете API rhino, а не API ScriptEngine, как описано в этом ответе:https://stackoverflow.com/a/16479685/1089998.
Я предпочитаю этот подход ответу Ноя, поскольку это означает, что вам не нужно выполнять случайный код javascript перед каждым выполнением.
У меня есть рабочий пример здесь: