2012-02-29 61 views
1

我想要访问当前处于JavaScriptObject属性但转换失败的Java对象。这是我做的:将JavaScriptObject转换为Java对象在GWT中失败

public static native MyJavaObject getMyObject(JavaScriptObject obj) /*-{ 
    return obj['myProp']; 
}-*/; 

obj.myProp是一个Java对象,它是由Java构造函数创建的(它在Javascript中可见,因为它被导出)。运行上述代码时的结果是在开发模式下的java.lang.ClassCastException。

但是,如果像下面这样做并访问秘密属性g它的作品!看起来,gwt在转换返回值时不会移除包装器。

public static native MyJavaObject getMyObject(JavaScriptObject obj) /*-{ 
    return obj['myProp'].g; 
}-*/; 

上面的代码工作,但它不是一个解决方案,因为它使用gwt中的实现细节。我究竟做错了什么?

感谢/约翰

通过测试发现的一些新的结论:

看来问题依赖于GWT出口国出口,因为我预计在本机代码不会被转换的对象。

  • 导出的对象被包装并且原始对象存储在名为g的属性中。
  • 由于GWT不知道这个,它不能从包装的导出对象中检索原始对象。
  • 当通过导出的接口进行包装和解包时是自动的。
  • 这个异常似乎是在本机方法中执行处理导出对象的代码时。本机方法的行为与定义为javascript的代码行为不同,因为它们似乎无法处理导出解包。这是通过尝试调用导出对象作为参数的导出方法找到的。它从本机代码失败,但从普通的JavaScript工作相同。

有人可以知道gwt-exporter中的实现细节来确认我的假设吗?

+0

Do MyJavaObject是否扩展了JavaScriptObject? 如果不这样做,请尝试这样做。 – Nicocube 2012-02-29 16:58:51

+0

请勿尝试这样做,或者确保使用适当的JSNI表示法引用该媒体资源,请参阅http://code.google.com/webtoolkit/doc/latest/DevGuideCodingBasicsJSNI.html#methods-fields – 2012-02-29 20:54:27

回答

1

现在我找到了一种方法来做到这一点。我的结论是,本机代码和普通JavaScript的处理方式有所不同,这取决于导出的类不在当前范围内,需要由$wnd作为前缀。

下面是我如何将我的JavaScriptObject转换为导出的类Icon。这有点尴尬,但它的工作原理并不取决于实施细节。

public class ConvertUtils implements Exportable { 

    private static Icon icon_; 

    public static Icon icon(JavaScriptObject obj) { 
     icon_ = null; 
     setIconNative(obj); 
     return icon_; 
    } 

    private static native void setIconNative(JavaScriptObject obj) /*-{ 
     $wnd.ravegeo.ConvertUtils.setIcon(obj); 
    }-*/; 

    @Export 
    public static void setIcon(Icon icon) { 
     icon_ = icon; 
    } 
} 

诀窍是通过导出的方法将对象转换为解包(setIcon方法)。