2013-03-13 124 views
1

我將JavaScript文件中的函數傳遞給Java代碼。 JavaScript函數如下所示:Java代碼中的JavaScript函數調用

entity.handler = function(arg1, arg2) { 
    //do something 
}; 

在Java代碼中,類實現了Scriptable接口。當我調用JavaScript中,實際上下面的方法被調用Java中:

Scriptable.put(java.lang.String s, org.mozilla.javascript.Scriptable scriptable, java.lang.Object o)

哪裏我的情況:

S = '處理';

腳本化 - 對象,其類型是com.beanexplorer.enterprise.operations.js.ScriptableEntity

-O - 實際上是一個函數,其類型爲org.mozilla.javascript.gen.c15(o instanceof Scriptable)返回true在調試器。

Scriptable.put()方法實現我想委派行動的「o」對象:

SomeClass.invoke(new SomeListener(){ 
    @override 
    public void someAction(int arg1, float arg2) { 
     //here I need to delegate to the 'o' object. 
     //do something looked like: 
     o.call(arg1, arg2); // have no idea how to do it, if it's possible. 
    } 
} 

我該怎麼辦呢?我找不到任何我的案例需要的例子。

謝謝。

編輯,解決方案: Actully o - 可以轉換爲函數。結果如下解決方案幫助:

@Override 
put(java.lang.String s, org.mozilla.javascript.Scriptable scriptable, java.lang.Object o) { 
    .... 
    final Function f = (Function)o; 
    final SomeInterface obj = new ...; 
    obj.someJavaMethod(Object someParams, new SomeJavaListener() { 
     @Override 
    public void use(Object par1, Object par2) throws Exception { 
     Context ctx = Context.getCurrentContext(); 
     Scriptable rec = new SomeJavaScriptableWrapperForObject(par1); 
      f.call(ctx, scriptable, scriptable, new Object[] { rec, par2 }); 
     } 
}); 
+0

從[腳本的API文檔](http://www.jarvana.com/jarvana/view/rhino/js/1.6R6/js-1.6R6-javadoc.jar!/org/mozilla/javascript/Scriptable。 HTML):'主機系統實現者可能會發現它更容易在編寫主機對象時擴展ScriptableObject類,而不是實現Scriptable。「我試着...... – ppeterka 2013-03-13 15:17:03

+0

如果我找到了正確的答案,您可以通過Java類擴展ScriptableObject,而不是實現接口。但無論如何,我必須重寫put方法,導致標準實現不適合。因此,我看不到擴展ScriptableObject類而不是實現接口的好處。 – Alexandr 2013-03-13 15:23:57

+0

你的觀點部分有效。然而,我會這麼做,因爲這樣做,你的代碼將變得更清晰,並且可能有助於發現問題的原因,這樣你就不必編寫所有代碼來開始工作......你只需要重寫「有用」的方法然後... – ppeterka 2013-03-13 15:43:04

回答

0

我設法通過下面的代碼來運行你的Javascript:

public class Main { 

    public static void main(String[] args) { 
     new ContextFactory().call(new ContextAction(){ 

      @Override 
      public Object run(Context ctx) { 
       Scriptable scope = ctx.initStandardObjects(); 
       try { 
        Scriptable entity = ctx.newObject(scope); 

        scope.put("console", scope, Context.javaToJS(System.out, scope)); 
        scope.put("entity", scope, entity); 

        ctx.evaluateReader(
         scope, 
         new InputStreamReader(Main.class.getResourceAsStream("/handler.js")), 
         "handler.js", 1, null); 

        Function handler = (Function) entity.get("handler", entity); 
        Object result = handler.call(ctx, scope, scope, new Object[] {"Foo", 1234}); 

        System.out.println("Handler returned " + result); 
       } catch (Exception e) { 
        e.printStackTrace(System.err); 
       } 
       return null; 
      } 
     }); 

    } 
} 

下面的腳本必須在handler.js適用於您的CLASSPATH:

entity.handler = function(arg1, arg2) { 
    console.println("Hello world from the JS handler"); 
    return 42; 
}