【问题标题】:Vaadin - grid.getDataProvider().refreshAll(); Does not work after updating browserVaadin - grid.getDataProvider().refreshAll();更新浏览器后无法使用
【发布时间】:2017-10-28 13:26:45
【问题描述】:

你好吗?更新包含我的网格的选项卡后,我有推送的详细信息,我使用的是 vaadin 8.0.4 ,谷歌浏览器更新了,我的例子基于这里https://github.com/vaadin/archetype-application-example

我的应用程序由存储在 mongodb 中的数据组成,当我在 db 中进行直接更改时,它每隔 30 秒就会反映在网格中,通过推送,它总是在单个选项卡上工作,当我出现问题时更新选项卡或创建一个新选项卡,推送似乎已断开连接,并且我的网格不再更新,奇怪的是我添加了 @PreserveOnRefresh 并在访问应用程序的第一个选项卡中,如果推送即使在之后仍然有效更新很奇怪。

此实例检查我的数据库中的更改

private ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(5);

我使用网格更新,与

grid.getDataProvider().refreshAll()

我什至尝试通过 12.16.4 书中描述的模式来广播标签。向其他用户广播 因为如果活动通知在所有选项卡中继续,但网格不会,仅在原始选项卡中。


更新: 在这个示例应用程序中,问题实际上是登录,当我删除它时,如果一切正常,因为它应该与推送一样。但只有当我删除登录

@Override
public void receiveBroadcast() {
   access(() -> {
    //Notification.show(message);
    //grid.getDataProvider().refreshAll();
    getNavigator().removeView(MonitorCrudView.VIEW_NAME);
    getNavigator().addView(MonitorCrudView.VIEW_NAME,new MonitorCrudView(this));
    getNavigator().navigateTo(MonitorCrudView.VIEW_NAME);
    Notification.show("Grid updated", Notification.Type.TRAY_NOTIFICATION);
   });
}

详细信息是,当我启用了 AccessContro,并以管理员身份输入时,执行上述方法时,我得到 “没有请求链接到当前线程”类型的异常;来自“CurrentUser”类 https://github.com/vaadin/archetype-application-example/blob/master/mockapp-ui/src/main/java/org/vaadin/mockapp/samples/authentication/CurrentUser.java

但在 vaadin 8.0.4 中发生了一些变化

public final class CurrentUser {

    /**
     * The attribute key used to store the username in the session.
     */
    public static final String CURRENT_USER_SESSION_ATTRIBUTE_KEY = CurrentUser.class
            .getCanonicalName();

    private CurrentUser() {
    }

    /**
     * Returns the name of the current user stored in the current session, or an
     * empty string if no user name is stored.
     * 
     * @throws IllegalStateException
     *             if the current session cannot be accessed.
     */
    public static String get() {
        String currentUser = (String) getCurrentRequest().getWrappedSession()
                .getAttribute(CURRENT_USER_SESSION_ATTRIBUTE_KEY);
        if (currentUser == null) {
            return "";
        } else {
            return currentUser;
        }
    }

    /**
     * Sets the name of the current user and stores it in the current session.
     * Using a {@code null} username will remove the username from the session.
     * 
     * @throws IllegalStateException
     *             if the current session cannot be accessed.
     */
    public static void set(String currentUser) {
        if (currentUser == null) {
            getCurrentRequest().getWrappedSession().removeAttribute(
                    CURRENT_USER_SESSION_ATTRIBUTE_KEY);
        } else {
            getCurrentRequest().getWrappedSession().setAttribute(
                    CURRENT_USER_SESSION_ATTRIBUTE_KEY, currentUser);
        }
    }

    private static VaadinRequest getCurrentRequest() {
        VaadinRequest request = VaadinService.getCurrentRequest();
        if (request == null) {
            throw new IllegalStateException(
                    "No request bound to current thread");
        }
        return request;
    }
}

更新:

Https://github.com/rucko24/testView/blob/master/MyApp-ui/src/main/java/example/samples/crud/SampleCrudView.java

在这个类中,我添加了向所有 UI 广播的按钮。

  • 以管理员身份登录
  • 点击更新网格
  • 应该给出类型异常

java.util.concurrent.ExecutionException: java.lang.IllegalStateException:没有请求绑定到当前线程

  • 刷新 UI 后不会继续抛出异常 但是在隐身标签中打开时,它总是在更新前抛出一次异常。

  • 加上基础项目和mongo db

私有静态 ScheduledExecutorService 调度程序 = Executors.newScheduledThreadPool(5);

我总是从上面得到相同的异常,并且从不使用 push 更改视图

【问题讨论】:

  • 您是否有机会在 github 或类似网站上分享 sscce(忘记数据库只使用一些静态数据),以及重现您的问题的步骤列表?
  • 非常感谢非常感谢,我正在尝试在没有 mongodb 的情况下重现错误,在应用程序本身示例 8.0.4 中,但我仍然没有实现。 @Morfic
  • 你好@Morfic你在某种程度上是哈哈哈哈,我不知道是不是问得太多了,但你能看到github中的代码吗?
  • 我检查了您的代码,请参阅下面的可能响应。 题外话:我目前正在旅行,所以我可能无法快速回复您的 cmets。

标签: grid vaadin


【解决方案1】:

免责声明:这更适合作为评论,但它不适合分配的空间。


VaadinService.getCurrentRequest() API doc 声明:

当前响应不能用于例如后台线程,因为服务器实现重用响应实例的方式。

同时,UI.access() javadoc 有点含糊地说:

请注意,runnable 可能在不同的线程上或稍后在当前线程上调用,这意味着执行命令时自定义线程局部变量可能没有预期值

上面的陈述解释了为什么VaadinService.getCurrentRequest() 在你的getCurrentRequest() 方法中为空。

不过,似乎 UI.getCurrent() 在后台线程中运行时会返回一个实例,this vaadin forum post 和 vaadin book 也建议这样做:

您的代码不是线程安全的,因为它不会在访问 UI 之前锁定 VaadinSession。首选模式是使用 UI.access 和 VaadinSession.access 方法,如 Book of Vaadin section 11.16.3. 中所述。在访问块内,除了正确处理会话锁定之外,Vaadin 还会自动设置相关的线程局部变量。

最后,我建议将所有对getCurrentRequest().getWrappedSession() 的调用替换为UI.getCurrent().getSession();例如:

UI.getCurrent().getSession().getAttribute(CURRENT_USER_SESSI‌​ON_ATTRIBUTE_KEY);

UI.getCurrent().getSession().setAttribute(CURRENT_USER_SESSI‌​ON_ATTRIBUTE_KEY, currentUser);

我用您的样品对此进行了测试,效果很好。

【讨论】:

  • 非常感谢您的帮助 我感谢您的帮助,如果浏览器运行良好,请更改浏览器以及使用我的 ScheduledExecutorService 进行更新,无需按钮,现在是 grid.getDataProvider ()。全部刷新();不会刷新所有 UI,但确实是第一个作品
猜你喜欢
  • 1970-01-01
  • 2016-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-20
  • 1970-01-01
相关资源
最近更新 更多