2014-03-31 108 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。 –