Vaadin - grid.getDataProvider()。refreshAll();更新浏览器后不起作用

时间:2017-05-27 22:21:42

标签: grid vaadin

你好吗?在更新包含我的网格的选项卡后,我有一个详细信息,我使用的是vaadin 8.0.4 ,Google Chrome已更新,我的示例基于https://github.com/vaadin/archetype-application-example

我的应用程序由存储在mongodb中的数据组成,当我在数据库中进行直接更改时,它经常在30秒内反映在网格中,使用push,它总是在单个选项卡上工作,当我在更新选项卡或创建一个新选项卡,推送似乎已断开连接,我的网格不再更新,奇怪的是我添加了@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时,我按照您所看到的那样输入admin,在执行上述方法时,我得到类型"没有链接到当前线程的请求&# 34; ;来自" 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

在这堂课中,我添加了向所有用户界面广播的按钮。

  • 以管理员身份登录
  • 点击更新网格
  • 应该提供类型例外
  

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

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

  • 使用基础项目和mongo db加上

  

private static Sc​​heduledExecutorService scheduler =   Executors.newScheduledThreadPool(5);

我总是从上面得到相同的例外,并且永远不会用push

更改视图

1 个答案:

答案 0 :(得分:1)

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

VaadinService.getCurrentRequest() API doc表示:

  

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

与此同时,UI.access() javadoc有些模棱两可,说明:

  

请注意,runnable可能在另一个线程上调用,或者稍后在当前线程上调用,这意味着执行命令时自定义线程本地可能没有预期的值

以上陈述有助于解释VaadinService.getCurrentRequest()方法中getCurrentRequest()为空的原因。

尽管如此,似乎UI.getCurrent()在后台线程中运行时返回一个实例,同样由this vaadin forum post和vaadin book建议:

  

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

总之,我建议将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);

我用你的样品进行了测试,结果很好。