【问题标题】:Calling GWT Java function from JavaScript从 JavaScript 调用 GWT Java 函数
【发布时间】:2025-12-04 02:50:02
【问题描述】:

我是 GWT 和 JavaScript 的新手。 我曾尝试遵循类似的此类问题,但一直失败。

我有一个 GWT 应用程序,我需要从 Javascript 调用一个 Java 函数(尤其是在 href 标记的 onclick 上。)以下是我所做的。

public class JSNITest {

 public static void handleAnchorClick(int a , int b) {
   Window.alert("Current row and Column is " + a + "  " + b);
 }

 public static native void exportMyFunction()/*-{
    $wnd.handleAnchorClick = function(param1,param2){
        @company.package.class.JSNITest::handleAnchorClick(*)(param1,param2);
 }-*/;

}

在 HTML 中,

<a href="javascript:handleAnchorClick(a1,a2);">link</a> 

(a1 , a2) 是我的代码中的两个整数变量。 我还在入口点函数中调用了 EnclosureClass.exportMyFunction()。 我不断遇到各种异常(没有此类异常)。有人可以纠正我吗?

问候

【问题讨论】:

    标签: gwt jsni gwtquery gwt-exporter


    【解决方案1】:

    让我解释一下关于将 GWT 内容导出到 JS 世界的更多信息。您有多种选择,但我将重点介绍三种方法。

    [编辑]

    0- JsInterop:GWT 维护人员正在开发一项新功能,可以轻松地将 java 方法导出到 javascript,并包装 javascript 对象。该功能在 2.7.0 中是非常实验性的,缺少一些功能,但在 2.8.0 中几乎可以使用。请查看邮件列表中的Design Document 和其他discussions

    [结束]

    1- JSNI:第一个是编写你自己的jsni,在这种情况下你必须意识到你可能犯的错误。基本上这些错误是因为你必须知道如何处理类型。在您的情况下,如果您想获得一个 javascript 数组(就像您在下面的评论中询问的那样),解决方案可能是:

    public static native void exportMyFunction()/*-{
      $wnd.handleAnchorClick = @company.package.class.JSNITest::handleAnchorClick(*);
    }-*/;
    
    public static void handleAnchorClick(JsArrayMixed args) {
      Window.alert("Current row and Column is " +
                    args.getNumber(0) + "  " + args.getNumber(1));
    }
    
    public void onModuleLoad() {
      exportMyFunction();
    }
    
    //javascript code
    window.handleAnchorClick([1,2])
    

    请注意,JSNI 只允许您传递primitive 类型(long 除外)和JavaScriptObject 对象。因此,当传递一个 javascript 数组时,您必须使用 JavaScriptObject 来接收它,就像示例中一样。在这种情况下,由于 javascript 只使用数字类型,args.getNumber 将始终返回双精度值,您必须在 java 中进行转换。

    2- gwt-exporter 对于导出大型项目,或者当您需要处理复杂的对象和类时,我宁愿使用gwt-exporter

    static class MyClass implements Exportable {
      @Export("$wnd.handleAnchorClick")
      public static void handleAnchorClick(double[] args) {
        Window.alert("Current row and Column is " +args[0] + "  " + args[1]);
      }
    }
    
    public void onModuleLoad() {
      GWT.create(MyClass.class);
    }
    
    //javascript code
    window.handleAnchorClick([1,2])
    

    gwt-exporter 将处理任何类型的原始类型(即使是 long)myfunc(long[] args),使用 var-args myfunc(long...args),它支持方法重载等等。

    3- gwtquery 最后,如果您更喜欢gwtquery,您可以使用一种技术将函数属性添加到任何js对象,例如window

    // The GQuery Properties object is able to wrap a java Function object
    // into an js property.
    Properties wnd = window.cast();
    wnd.setFunction("handleAnchorClick", new Function() {
      public void f() {
        // Get the js arguments[] array
        JsArrayMixed args = arguments(0);
        // Get the first element of the arguments[] array
        JsArrayMixed ary = args.getObject(0);
    
        Window.alert("Current row and Column is " +
                      ary.getNumber(0) + "  " + ary.getNumber(1));
      }
    });
    
    //javascript code
    window.handleAnchorClick([1,2])
    

    使用 gquery,您可以使用 gwt JsArrayMixed 类,它始终将数字作为双精度返回,或者您可以使用 JsCache,它允许将数字转换为 java 中的任何其他数字类型 ((JsCache)ary.get(1, Integer.class)

    作为总结,我宁愿使用 gwt-exporter 作为第一个选项,因为它专门处理这个问题。作为第二种选择,我会使用 gquery,它是 gwt 的重要补充。最后,我会尽可能避免使用手写 jsni,Javascript 通常是问题和错误的来源(认为 gwt 的主要目标不是处理 js)。

    【讨论】:

    • 嗯。才发现出了什么问题。我错误地给出了函数的路径。 :D。该死的。
    • 我只是想问你,我在调用时是否可以将 java 数组传递给 javascript 函数?如果是,怎么做?
    • 编辑了我的答案以解释如何使用不同的选项来处理它
    • 非常感谢您的宝贵时间。这是一个很好的答案,比我在网上浏览获得的信息要多得多:P!我有一个最终查询,说我想发送一个 int[] vars ,语法会有什么不同吗?在您的示例中,您使用了 [1,2]。
    • 你只能发送数字,因为在js中你只有数字。根据您选择的解决方案,您必须手动进行转换。编辑了我的答案。
    【解决方案2】:

    您应该考虑 GWT 导出器。您甚至可以考虑等待,因为 GWT 2.8 应该很快就会出来。它应该会在 2015 年的乞讨前后发布。2015 年已经开始,他们现在正在 GWT.create 上展示,所以它应该会在任何一天发布。如果你等不及了,那么你可以使用实验性的互操作,JSNI 就像上面的答案所说的那样,或者 GWT 导出器。 JSNI 比较复杂,涉及很多样板代码,所以如果你必须做很多 js 互操作,我推荐 GWT-exporter。

    【讨论】: