2012-07-05 53 views
3

的Javascript我有以下代碼:如何從JSObject轉換爲地圖(反之亦然),或列出JSObject成員

var r=applet.foo({var0:99,var1:'foo',var2:applet}); 

在我的Java小程序,我有以下幾點:

public JSObject foo(JSObject args){ 
    System.out.println("The function is correctly invoked"); 
    //In fact, the following works perfectly: 
    System.out.println("var1 is:"+(String)args.getMember("var1")); 
    JSObject w=JSObject.getWindow(this); 
    JSObject j=(JSObject)w.eval("new Object();"); 
    Map m=new Hashmap(); 

    //TODO here all the keys and values of args should be added to m 

    m.put("hello","world"); 

    //TODO here all the keys and values of m should be added to j 

    return j; 
} 

這怎麼辦? (待辦事項


閱讀http://docstore.mik.ua/orelly/web/jscript/ch19_06.html,我發現那裏有一個getSlot方法JSObject,但如果我這樣做

args.getSlot(0) 

我只有一個例外:

netscape.javascript.JSException: No such slot 0 on JavaScript object 
... 

回答

1

作爲解決方案,您可以根據建議here定義方法keys(您可以在您的java代碼中使用JSObject.eval(...))。然後,你可以得到這樣的鍵:

JSObject keys = (JSObject)args.call("keys", Collections.EMPTY_LIST); 
keys.getSlot(0); 
+1

爲了獲得密鑰,不需要定義'keys'方法。使用'eval'方法就足夠了,因爲它在'JSObject'的上下文中執行JavaScript代碼:'JSObject keys =(JSObject)args.eval(「Object.keys(this)」);' – Ezze 2012-12-19 18:25:36

3

不幸的是,Errandir的解決方案僅當你知道可以用來訪問你想獲得性的名字對象的全局變量的名稱。您需要知道該名稱才能夠將keys方法添加到對象,並在稍後使用JSObjectcall方法調用該方法。當然,如果你有對象的話,你可以把對象的全局名稱傳給Java。這個解決方案看起來不太好,特別是當你不能在全局上下文中引用你的對象時。

作爲一種替代方案,我建議在評論中使用JSObjecteval方法中的this,假設它將完成所有工作。它確實如此。但令人大失所望的是,它只能在Mozilla Firefox和Opera中使用。在Internet Explorer 9和Google Chrome中(在Windows 7和Ubuntu 12.04 LTS下測試)thiseval方法總是指小程序的文檔窗口,忽略實例中實際代表的是哪個JavaScript對象。我不知道這是一個錯誤還是簡單LiveConnect在這些瀏覽器中支持很差。

好消息是call方法JSObject在正確的上下文中執行指定的函數。牢記這一點,我終於找到了一個解決方案,可以如何檢索JavaScript對象屬性的名稱列表。這個想法是使用eval方法在全局範圍內定義一個臨時函數。這個函數必須接收一個JavaScript對象,我們要獲取屬性並將這些屬性的名稱作爲數組返回。之後,我們可以通過JSObjectcall方法調用臨時函數,通過傳遞相關JavaScript對象的Java表示(在我的方法中爲jsObject,或者在問題中聽起來爲args)。最後,臨時函數可以被刪除。

public static ArrayList<String> getJsObjectPropertiesNames(Applet applet, JSObject jsObject) { 

    if (applet == null || jsObject == null) 
     return null; 

    // Retrieving global context - a JSObject representing a window applet belongs to 
    JSObject globalContext; 
    try { 

     globalContext = JSObject.getWindow(applet); 
    } 
    catch (JSException ex) { 

     return null; 
    } 

    // Checking whether passed object is not an array 
    try { 

     jsObject.getSlot(0); 
     return null; 
    } 
    catch (JSException e) { 

    } 

    String keysFunctionName = String.format("_getKeys%d", Calendar.getInstance().getTimeInMillis()); 
    jsObject.eval("window['" + keysFunctionName + "'] = function(jsObject) { return Object.keys(jsObject) }"); 
    JSObject propertiesNamesJsObject = (JSObject)globalContext.call(keysFunctionName, new Object[] { jsObject }); 
    jsObject.eval("delete(window['" + keysFunctionName + "'])"); 

    ArrayList<String> propertiesNames = new ArrayList<>(); 
    try { 

     int slotIndex = 0; 
     while (true) { 

      Object propertyName = propertiesNamesJsObject.getSlot(slotIndex); 
      if (propertyName instanceof String) 
       propertiesNames.add((String)propertyName); 
      slotIndex++; 
     } 
    } 
    catch (JSException e) { 

    } 

    return propertiesNames; 
} 
-1

下面我打印一個字符串,請修改它以獲得您需要的任何內容。

public final static String getKeys = "{var keys = [];for (var key in this) {keys.push(key);} keys;}"; 

private static String printProperties(final Object o, 
             final boolean printType, 
             final int level, 
             final String tab) { 
    final StringBuilder sb = new StringBuilder(100); 
    if (printType) { 
     sb.append("("); 
     sb.append(o.getClass().getSimpleName()); 
     sb.append(") "); 
    } 
    if (o instanceof JSObject) { 
     sb.append("{\n"); 
     final JSObject js = (JSObject) o; 
     final JSObject keys = (JSObject) js.eval(getKeys); 
     boolean needComma = false; 
     for (int i = 0;; i++) { 
      final String key = (String) keys.getSlot(i); 
      if ((key != null) && !(key.equals("undefined"))) { 
       final Object val = js.getMember(key); 
       if (!needComma) { 
        needComma = true; 
       } else { 
        sb.append(",\n"); 
       } 
       sb.append(multitab(tab, level)); 
       sb.append(key); 
       sb.append(":"); 
       sb.append(printProperties(val, printType, level + 1, tab)); 
      } else { 
       break; 
      } 
     } 
     sb.append("\n"); 
     sb.append(multitab(tab, level - 1)); 
     sb.append("}"); 
    } else { 
     sb.append(o); 
    } 
    return sb.toString(); 
} 

private final static String tab = " "; 

private static String multitab(final String tab, 
           int i) { 
    final StringBuilder sb = new StringBuilder(); 
    while (i-- > 0) { 
     sb.append(tab); 
    } 
    return sb.toString(); 
}