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

Vaadin:如何从其他线程实时更新Grid组件数据?

解决Vaadin Grid后台线程更新不即时显示的问题

问题分析

你的代码存在两个核心问题导致数据无法自动刷新:

  1. 全局存储UI.getCurrent()实例有风险,若用户在异步操作完成前切换页面/刷新,该实例可能已失效。
  2. 未启用Vaadin的Push推送机制,后台线程更新UI后无法主动同步到客户端,只能等用户交互触发请求才会更新。

修复方案

1. 启用Push功能

Push是Vaadin实现后台UI更新主动推送的核心机制,配置方式如下:

  • 若为Spring Boot项目,在application.properties中添加:
vaadin.push.enabled=true
vaadin.push.mode=automatic
  • 或直接在你的UI类上添加注解:
@Push
public class YourMainUI extends UI {
    // 你的UI逻辑
}

2. 修正后台线程更新代码

不要全局缓存UI实例,改用Vaadin官方推荐的安全更新方式,同时移除不必要的页面重载:

taskSlaService.getFilterAsync(pointId, dictValueIds)
        .thenAcceptAsync(entities -> {
            log.info("entities {}", entities);
            if (entities.isEmpty()) {
                log.info("entities is empty =====> {}", entities);
            }
            // 通过VaadinSession执行UI更新,自动处理线程安全
            VaadinSession.getCurrent().access(() -> {
                UI ui = UI.getCurrent();
                if (ui != null) {
                    log.info("========> UI isn't null");
                    grid.setItems(entities);
                    // setItems已完成数据替换,无需额外调用refreshAll
                    log.info("entities in UI.access =====> {}", entities);
                    log.info(Thread.currentThread().getName());
                    // 移除页面重载,这会覆盖异步更新的效果
                    // ui.getPage().reload();
                }
            });
        });

关键注意事项

  • 禁止全局存储UI或VaadinSession实例,它们与用户会话绑定,随时可能失效。
  • 所有UI更新操作必须放在VaadinSession.access()或UI.access()中执行,这会自动处理锁机制和线程安全。
  • 启用Push后,后台线程的UI变更会直接推送到客户端,无需用户交互触发。

内容的提问来源于stack exchange,提问作者Алексей Шерстобитов

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 03:47:46