java - JSNI Marshal Enum 可以作为字符串吗?

标签 java javascript gwt marshalling jsni

我正在尝试使用 GWT 的 JSNI 通过 native 代码调用 Java 函数。 Java 函数中有一个枚举,我很好奇该枚举是否会按照我想要的方式进行编码。我在 Google 或 SO 上找不到任何有用的东西,并且 the Google basic docs不是很具体。我确信我会在编译和运行时找到答案,但我想我不妨问一下。

给出像这样大大简化的代码:

package my.example.package;
public class Giant {
    public enum GiantWord { FEE, FIE, FO, FUM };
    public void sayGiantWord(GiantWord word) { /* ... */ }

    public native JavaScriptObject toJS() /*-{
        var Giant = function() {
            this.sayGiantWord = function(word) {
                this.@my.example.package::sayGiantWord(Lmy/example/package/Giant$GiantWord;)(word);
            };
        };
        return new Giant();
    }-*/;
}

编辑 - 根据评论,让我给出 toJS 函数的替代版本,并避免 thisthis 之间发生混淆。

    public static native JavaScriptObject toJS(final Giant g) /*-{
        var Giant = function() {
            this.sayGiantWord = function(word) {
                g.@my.example.package::sayGiantWord(Lmy/example/package/Giant$GiantWord;)(word);
            };
        };
        return new Giant();
    }-*/;

从 JavaScript 中调用 sayGiantWord("FEE")(在从 toJS() 中适当获取的 var 上)可以正常工作吗?换句话说,JSNI 编码器能否正确地将 String 转换为其匹配的 Java 枚举?

我希望调用 sayGiantWord(1) 更容易正确编码,因为 int 可以轻松转换为枚举。

其他说明:

  • GWT Eclipse 插件为我提供了访问类成员枚举的语法。至少到目前为止,GWT 正在与我合作。
  • 我不想传递数字,如果有必要,我知道我可以使用 Java 类中的转换函数处理字符串,如下所示;我只是不想这样做。
public void sayGiantWordJS(String word) {
    // convert the string to an enum
    // call sayGiantWord
}

感谢您的建议!

最佳答案

JSNI 无法处理 Java 枚举,但您可以将枚举字符串传递到 JSNI 层,以及将从 JSNI 方法返回的字符串转换回枚举。

您最好单独表示 Giant JavaScript 对象,并从 Giant Java 类型委托(delegate)给 JSNI 层。这样您就可以保持关注点分离并松散地耦合实现和抽象:

public class GiantJso extends JavaScriptObject {

    protected GiantJso() {
    }

    public static final native GiantJso create(String wordA, String wordB,
            String wordC) /*-{
        return {
            vocabulary : [ wordA, wordB, wordC ],
            said : ''
        };
    }-*/;

    public final native void sayGiantWord(String word) /*-{
        if (this.vocabulary.indexOf(word) != -1) {
            console.log("i'm a giant, here me roar: ", word, "!");
            this.said = word;
        }
    }-*/;

    public final native JsArrayString vocabulary() /*-{
        return this.vocabulary || null;
    }-*/;

    public final native String said() /*-{
        return this.said;
    }-*/;
}

然后将其包装在 Java 类型中:

public class Giant {

    private GiantJso jso;

    public Giant() {
        jso = GiantJso.create(GiantWord.FEE.name(),
                GiantWord.FEE.name(), GiantWord.FEE.name());
    }

    public void sayGiantWord(GiantWord word) {
        jso.sayGiantWord(word.name());
    }

    public GiantWord getSaidWord() {
        return GiantWord.valueOf(jso.said());
    }
}

vocabularysaid 只是可以分配给 JSO 的其他属性的示例,当然,您可以自由地实现您希望的任何结构。

进一步阅读

注意:如果您想要将 Java 类表示为 JavaScript 构造,请查看 GWT exporter .

关于java - JSNI Marshal Enum 可以作为字符串吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14963306/

相关文章:

java - 如何模拟传出的套接字连接?

javascript - 使用 form.submit() 清空 $_GET 和 $_POST

javascript - 如何在 gwt datepicker 中禁用当天的点击事件?

html - 使用GWT和AppEngine Blobstore上传多个文件?

java - GWT - 在 RPC 服务调用期间获取 session

java - 为什么这个 Java 正则表达式不起作用?

java - 获取另一个Java进程的工作目录

java - Spring Boot : SpringApplication. 运行导致 org.springframework.context.ApplicationContextException:

javascript - 如果子 ul 没有可见元素,则隐藏字段集

javascript - 如何使用 javascript 从网站下载时重命名文件?