2014-03-31 40 views
1

我一直在使用rhino来允许一些应用程序的定制。下面是一个从Java调用的JavaScript函数的示例:获取JavaScript对象的字段值

 function() { 
      var phone = this.telephoneNumber; 
      phone = phone.replace(/[^+0-9]/g,""); 
      if (phone.indexOf("+") == 0) { 
       phone = "00" + phone.substring(1); 
      } 
      if (phone.indexOf("0041") == 0) { 
       phone = "0" + phone.substring(4); 
      } 
      if (phone.indexOf("0") == 0) { 
       phone = "0" + phone; 
      } 
      return { 
       Name: this.sn + " " + this.givenName, 
       firstName: this.givenName || "", 
       lastName: this.sn || "", 
       phone: phone, 
       service: "", 
       info: "" 
      }; 
     } 

然后,java应用程序可以获取返回对象的值,无论它需要做什么。

既然rhino是JVM的一部分,我想使用脚本API而不是Rhino API,但是我还没有找到如何从Java代码中获取JavaScript对象的字段值。

+0

Rhino不是* JVM的一部分;它是运行时的一部分。这就像Java只是使用Xalat的补丁版本Xalan一样。除非他们在运行时对Rhino的版本进行了大量优化,但是无法将优化重新提供给Rhino,否则您无法取得任何显着的性能提升。此外,你得到一个旧版本的犀牛。 –

+0

@DavidEhrmann是的,目的不是为了获得性能改进,而是使用标准脚本引擎API,以便切换到其他脚本语言更容易。 –

回答

1

这松散地结合了脚本语言,但是要注意函数需要命名,并且返回的对象需要是Map(Rhino这样做,但我不确定JRuby)。

ScriptEngineManager factory = new ScriptEngineManager(); 
    ScriptEngine engine = factory.getEngineByName("JavaScript"); 
    engine.eval("function x() { return { foo: 10 } }"); 

    Object o = ((Invocable)engine).invokeFunction("x"); 
    if (o instanceof Map) { 
    Map m = (Map<Object, Object>)o; 
     System.out.println(m.get("foo")); 
    } 

CompiledScript script = ((Compilable)engine).compile("(function() { return {bar:20} })()"); 
    System.err.println(((Map)script.eval()).get("bar")); 

但是你要作弊,并通过与(...)()填充它调用你的函数。

+1

够公平的。它只适用于1.7+,但...我想是时候停止支持旧版本了......有趣的细节:1.7返回一个Double,而1.8返回一个整数。 –

+0

如果您找到适用的JSR JAR,您应该可以在Java 6中运行它。我记得必须用StAX和Java 5来做到这一点。有趣的发现与双。 Javascript数字在技术上都是双打的,所以我认为这是有道理的。当你键入check时,一定要使用Number,然后使用intValue()。 –

+0

它与java 6一起工作,除了该对象不是一个Map。 –