Rhino Javascript:如何将对象转换为 Javascript 原语?

发布于 2024-08-08 05:17:31 字数 1203 浏览 6 评论 0原文

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

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

我如何强制它转换为 JavaScript 原语?

这个问题非常类似于 http://群组。 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

I am utilizing the javax.scripting with Rhino
in this project.

I have a Java method that returns a Java Object (Double, Long,
Integer, etc). I want to call that method from javascript and
reference the result as a Javascript primitive type. However,
javacript recognizes the return type as an Object.

How do I force it to convert to a javascript primitive?

This question is very similar to
http://groups.google.com/group/mozilla.dev.tech.js-engine.rhino/browse_thread/thread/2f3d43bb49d5288a/dde79e1aa72e1301

The problem with that is how do I get a reference to the context and
the WrapFactory?

Sample Code:

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

Output:
Result: 15

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

萌酱 2024-08-15 05:17:31

尝试以下

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

Try the following

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

Alternatively, you could modify the javascript function to explicitly cast the value to a number:

function test(data) { return parseInt(data.get('value1'), 10) + 5;}
谢绝鈎搭 2024-08-15 05:17:31

使用以下内容作为 JavaScript 代码中的输出:

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

Use the following as the output in your JavaScript code :

function aFunction(data)
{
  return parseInt(data);
}
爱殇璃 2024-08-15 05:17:31

我开发了这个应用程序,您可以在其中输入一组数学公式,这些公式将由 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 引擎非常快,所以这对我们来说不是问题。

I developed this application where you enter a set of mathematical formulas that will be evaluated by the JavaScript engine built into Java 6, which I believe is a port of rhino. The idea was that we would have a set of maps and these maps would contain variables, such as:

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

I used that approach as some of the expressions for the formulas came from variables that were under my control and that could be invalid JS identifiers. My first approach was to declare a map and add it to the JS engine, but it failed in the same way that it's failing with you - it was interpreting it as a string, and not as a number.

The solution was to parse the formula, figure out what variables are being used by it, and then declare the object inside the JS engine.

Something like this:

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

And thenMAP["VALUE 1"] + MAP["VALUE 2"] will return 3, and not 12.

There may be a better solution around, but once you go around the initial coding/ parsing, the above will always work. In our case there's a phase where we execute the "declarative" statements, and another phase where we execute the formulas. The JS engine is REALLY fast, so it's not a problem for us.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文