Rhino Javascript: Как преобразовать объект в примитив Javascript?

Я использую javax.scripting с Rhino в этом проекте.

У меня есть метод Java, который возвращает объект Java (Double, Long, Integer и т. Д.). Я хочу вызвать этот метод из javascript и ссылаться на результат как примитивный тип Javascript. Однако javacript распознает тип возвращаемого значения как Object.

Как заставить его преобразовать в примитив JavaScript?

Этот вопрос очень похож на http://groups.google.com/group/mozilla.dev.tech.js-engine.rhino/browse_thread/thread/2f3d43bb49d5288a/dde79e1aa72e1301

Проблема в том, как мне получить ссылку на контекст и WrapFactory?

Образец кода:

public class data 
{ 
   Double value = 1.0d; 
   public Number get()  {  return value; } 
} 


  public static void main(String[] args) 
    { 
            ScriptEngine engine = new ScriptEngineManager().getEngineByName ("rhino"); 
            data data = new data(); 
            try 
            { 
                    engine.eval("function test(data) { return data.getD('value1') + 5;};"); 
                    System.out.println("Result:" + ((Invocable)engine).invokeFunction("test", data)); 
            } 
            catch (Exception e) 
            { 
                    e.printStackTrace(); 
            } 
    } 

Выход: Результат: 15

3 ответа

Решение

Попробуйте следующее

 public static void main(String [] args) throws Exception {
        ScriptEngine engine = new ScriptEngineManager().getEngineByName ("rhino"); 
        data data = new data();
        Context.enter().getWrapFactory().setJavaPrimitiveWrap(false);

        try 
        { 
                engine.eval("function test(data) { return data.get('value1') + 5;};"); 
                System.out.println("Result:" + ((Invocable)engine).invokeFunction("test", data)); 
        } 
        catch (Exception e) 
        { 
                e.printStackTrace(); 
        } 
    }

    public static class data 
    { 
       Double value = 1.0d; 
       public Number get(String arg)  {  return value; } 
    } 

Кроме того, вы можете изменить функцию javascript, чтобы явным образом приводить значение к числу:

function test(data) { return parseInt(data.get('value1'), 10) + 5;}

Используйте следующее как вывод в своем коде JavaScript:

function aFunction(data)
{
  return parseInt(data);
}

Я разработал это приложение, в котором вы вводите набор математических формул, которые будут оцениваться механизмом JavaScript, встроенным в Java 6, который, как я считаю, является портом носорога. Идея заключалась в том, что у нас будет набор карт, и эти карты будут содержать переменные, такие как:

MAP["VALUE 1"]
MAP["VALUE 2"]

Я использовал этот подход, так как некоторые выражения для формул пришли из переменных, которые были под моим контролем и которые могли быть недействительными идентификаторами JS. Мой первый подход состоял в том, чтобы объявить карту и добавить ее в движок JS, но она потерпела неудачу так же, как и с вами - она ​​интерпретировала ее как строку, а не как число.

Решением было проанализировать формулу, выяснить, какие переменные используются ею, а затем объявить объект внутри механизма JS.

Что-то вроде этого:

var MAP = new Object();
MAP["VALUE 1"] = 1;
MAP["VALUE 2"] = 2;

А потомMAP["VALUE 1"] + MAP["VALUE 2"] вернусь 3, и не 12,

Может быть лучшее решение, но как только вы начнете кодировать / анализировать, вышеприведенное будет работать всегда. В нашем случае есть фаза, где мы выполняем "декларативные" операторы, и другая фаза, где мы выполняем формулы. Двигатель JS действительно быстрый, поэтому для нас это не проблема.

Другие вопросы по тегам