【问题标题】:Rhino Javascript: How to convert Object to a Javascript primitive?Rhino Javascript:如何将对象转换为 Javascript 原语?
【发布时间】:2011-09-05 00:23:05
【问题描述】:

我在 Rhino 中使用 javax.scripting 在这个项目中。

我有一个返回 Java 对象的 Java 方法(Double、Long、 整数等)。我想从 javascript 调用该方法和 将结果引用为 Javascript 原始类型。然而, javacript 将返回类型识别为 Object。

如何强制它转换为 javascript 原语?

这个问题与 http://groups.google.com/group/mozilla.dev.tech.js-engine.rhino/browse_thread/thread/2f3d43bb49d5288a/dde79e1aa72e1301

问题是我如何获得对上下文的引用和 包装工厂?

示例代码:

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

【问题讨论】:

    标签: java javascript rhino


    【解决方案1】:

    试试下面的

     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;}
    

    【讨论】:

    • 这给了我一个 NullPointerException。 Context.getCurrentContext() 为空
    • 无效。仍然得到:结果:15
    • 抱歉,我之前的回复是在您更新“替代”部分之前。嗯......替代工作!它不太理想..但它有效。我将把这个问题留几天,以防有更正式的方式来解决这个问题
    • 是的,看起来它是作为字符串传入的。尝试按照@Kevin 的建议进行投射或使用engine.eval("function test(data) { return (+data.getD('value1')) + 5;};");
    【解决方案2】:

    在您的 JavaScript 代码中使用以下输出:

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

    【讨论】:

      【解决方案3】:

      我开发了这个应用程序,您可以在其中输入一组数学公式,这些公式将由 Java 6 中内置的 JavaScript 引擎进行评估,我相信 Java 6 是 rhino 的一个端口。我们的想法是我们将有一组地图,这些地图将包含变量,例如:

      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 引擎真的很快,所以这对我们来说不是问题。

      【讨论】:

        猜你喜欢
        • 2014-07-24
        • 2010-11-28
        • 1970-01-01
        • 2016-12-26
        • 2018-04-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多