从 Singleton 调用 Vaadin 组件上的 bean 方法
Invoke bean method on Vaadin component from Singleton
我正在尝试从 Singleton 更新简单的 Vaadin UI 组件:
这里是组件:
public class MaintenanceModeLogoutMessageLayout extends HorizontalLayout {
public MaintenanceModeLogoutMessageLayout() {
addComponent(new Label("test"));
}
public void changeVisibility(final Boolean visible) {
setVisible(visible);
}
这是我的单例,我需要在启动时运行
@Singleton
@Startup
public class SingletonTest {
private void executeMaintenanceModeChange(final Boolean maintenance) {
try {
final BeanManager beanManager = InitialContext.doLookup("java:comp/BeanManager");
final Set<Bean<?>> beans = beanManager.getBeans(MaintenanceModeLogoutMessageLayout.class);
final Bean<?> bean = beanManager.resolve(beans);
final CreationalContext<?> cc = beanManager.createCreationalContext(bean);
final MaintenanceModeLogoutMessageLayout object = (MaintenanceModeLogoutMessageLayout) beanManager.getReference(bean,
MaintenanceModeLogoutMessageLayout.class, cc);
if (object == null) {
LOG.warning("Cant find any bean for class " + MaintenanceModeLogoutMessageLayout.class.getSimpleName());
return;
}
Method method = bean.getBeanClass().getDeclaredMethod("changeVisibility", Boolean.class);
method.invoke(object, maintenance);
} catch (final NamingException | IllegalArgumentException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
LOG.log(Level.SEVERE, "Can't lookup object ");
}
}
}
如您所见,我正在触发事件,试图找到现有的 bean 并调用此对象的方法。
但问题是,即使它是当前的 bean,UI.getCurrent()
也是 null
。
如果我要创建组件 @UIScoped
我会遇到异常
Caused by: java.lang.IllegalStateException: Session data not
recoverable for Managed Bean
如何访问 UI?我如何以这种方式更新 Vaadin 组件?
你的问题是这个问题的变体,答案是一样的。
基本上,您的 tomcat/servlet 引擎中会有多个 UI 实例 运行。 (每个 user/browser 至少一个)
因此您必须将消息广播到 UI 的所有实例,然后适当地处理它。
如果它应该有异步(无需用户操作),那么您还需要启用推送,以便将消息推送到客户端网络浏览器。
否则它只会在下一次用户与 vaadin 应用程序交互时显示。
我正在尝试从 Singleton 更新简单的 Vaadin UI 组件:
这里是组件:
public class MaintenanceModeLogoutMessageLayout extends HorizontalLayout {
public MaintenanceModeLogoutMessageLayout() {
addComponent(new Label("test"));
}
public void changeVisibility(final Boolean visible) {
setVisible(visible);
}
这是我的单例,我需要在启动时运行
@Singleton
@Startup
public class SingletonTest {
private void executeMaintenanceModeChange(final Boolean maintenance) {
try {
final BeanManager beanManager = InitialContext.doLookup("java:comp/BeanManager");
final Set<Bean<?>> beans = beanManager.getBeans(MaintenanceModeLogoutMessageLayout.class);
final Bean<?> bean = beanManager.resolve(beans);
final CreationalContext<?> cc = beanManager.createCreationalContext(bean);
final MaintenanceModeLogoutMessageLayout object = (MaintenanceModeLogoutMessageLayout) beanManager.getReference(bean,
MaintenanceModeLogoutMessageLayout.class, cc);
if (object == null) {
LOG.warning("Cant find any bean for class " + MaintenanceModeLogoutMessageLayout.class.getSimpleName());
return;
}
Method method = bean.getBeanClass().getDeclaredMethod("changeVisibility", Boolean.class);
method.invoke(object, maintenance);
} catch (final NamingException | IllegalArgumentException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
LOG.log(Level.SEVERE, "Can't lookup object ");
}
}
}
如您所见,我正在触发事件,试图找到现有的 bean 并调用此对象的方法。
但问题是,即使它是当前的 bean,UI.getCurrent()
也是 null
。
如果我要创建组件 @UIScoped
我会遇到异常
Caused by: java.lang.IllegalStateException: Session data not recoverable for Managed Bean
如何访问 UI?我如何以这种方式更新 Vaadin 组件?
你的问题是这个问题的变体,答案是一样的。
基本上,您的 tomcat/servlet 引擎中会有多个 UI 实例 运行。 (每个 user/browser 至少一个)
因此您必须将消息广播到 UI 的所有实例,然后适当地处理它。
如果它应该有异步(无需用户操作),那么您还需要启用推送,以便将消息推送到客户端网络浏览器。 否则它只会在下一次用户与 vaadin 应用程序交互时显示。