You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Vaadin 8的Page.getCurrent().getJavaScript().addFunction迁移至Vaadin Flow 14?

Vaadin 8 到 Vaadin Flow 14:JavaScript 交互代码迁移方案

Vaadin Flow 14 废弃了 Vaadin 8 中通过 Page.getCurrent().getJavaScript().addFunction() 注册全局JS可调用方法的方式,改用**@ClientCallable**注解配合客户端脚本绑定的方式实现JS与Java的交互,以下是具体迁移步骤:

一、Java 端代码改造

将原来注册全局函数的逻辑迁移到UI组件类中,用@ClientCallable标记供JS调用的方法,并通过executeJs将全局JS函数绑定到组件的服务端方法:

import com.vaadin.flow.component.ClientCallable;
import com.vaadin.flow.component.AttachEvent;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.Route;
import java.util.concurrent.CompletableFuture;

@Route("")
public class MainView extends VerticalLayout {

    @Override
    protected void onAttach(AttachEvent attachEvent) {
        super.onAttach(attachEvent);
        // 注册全局getDocument函数,绑定到当前组件的服务端方法
        attachEvent.getUI().getPage().executeJs("""
                window.getDocument = function(signerResponse, procedure, messageId) {
                    $0.$server.getDocument(signerResponse, procedure, messageId);
                }
                """, this);
    }

    @ClientCallable
    public void getDocument(String signerResponse, String procedure, String messageId) {
        // 保留原有的Java REST调用逻辑
        // ...
    }

    // 如果需要向JS返回结果,可返回CompletableFuture
    @ClientCallable
    public CompletableFuture<String> getDocumentWithResult(String signerResponse, String procedure, String messageId) {
        // 执行REST调用并获取结果
        String restResult = executeRestCall(signerResponse, procedure, messageId);
        return CompletableFuture.completedFuture(restResult);
    }

    // 模拟REST调用方法
    private String executeRestCall(String signerResponse, String procedure, String messageId) {
        // ... 原有REST调用逻辑
        return "处理完成";
    }
}

关键说明:

  • @ClientCallable:标记该方法允许客户端JS通过组件的$server对象调用。
  • executeJs:将全局的getDocument函数指向当前组件的服务端方法,$0对应传入的组件实例this。
  • onAttach:确保组件挂载到UI后再注册JS函数,避免未初始化时调用出错。

二、JavaScript 端代码调整

原有的JS调用逻辑无需大幅修改,因为我们已经将全局getDocument函数绑定到了服务端方法,可直接保留原有代码:

window.documentSign = function(signerUrl, procedure) {
    // ... 原有逻辑
    getDocument(signerRequest.responseText, procedure, messageId);
    // ... 原有逻辑
}

如果需要接收Java端返回的结果,可改用异步调用方式:

async function documentSignWithResult(signerUrl, procedure) {
    // ... 原有逻辑
    let result = await getDocument(signerRequest.responseText, procedure, messageId);
    // 处理返回结果
    console.log("Java端返回结果:", result);
}

三、注意事项

  • 参数类型匹配:JS与Java间的参数会自动转换,确保JS传递的参数类型与Java方法参数类型兼容(如JS字符串对应Java String,数字对应Integer/Double等)。
  • 组件生命周期:避免在组件未挂载时注册JS函数,推荐在onAttach方法中执行注册逻辑。
  • 全局函数冲突:如果页面中有多个组件注册同名全局函数,需注意命名空间隔离,可改用组件特定的调用方式避免冲突。

内容的提问来源于stack exchange,提问作者aha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 08:50:46