提问者:小点点

在Vaadin 14 (Vaadin流)中呈现AppLayout之前,如何在视图中重新路由BeforeEnterObserver


例如,我有:

public class MainView extends AppLayout {
   public MainView() {
      User user = VaadinSession.getAttribute("user");
      if(user.isCheckSomething())
          Span span = new Span("Hello " + user.getFirstname());
   }
}

如果用户尚未登录,则此操作将失败,因为从会话获取用户将为空。现在,我可以在if(user.isCheckSomething())之前添加一个空检查,但理想情况下,如果用户未登录,我更希望不呈现AppLayout。也就是说,我宁愿在视图中通过public void beforeEnter(BeforeEnterEvent事件)方法中的BeforeEnterObserver失败,但在调用beforeEnter方法之前调用并创建了AppLayout

换句话说,如果用户没有通过视图登录,我如何强制完全跳过AppLayout的实例化,从而永远不会构造AppLayout


共1个答案

匿名用户

根据经验,在构造函数中以任何方式使用UI都是不可靠的,因为它还没有初始化。

AppLayout有自己的afterNavigation方法,应该在BeforeEnterEvent之后调用。

public class MainView extends AppLayout {
    @Override
    protected void afterNavigation() {
        super.afterNavigation();
        User user = VaadinSession.getAttribute("user");
        if(user.isCheckSomething())
            Span span = new Span("Hello " + user.getFirstname());
    }

因此,在 beforeEnter 方法中,您将重新路由到登录,否则将触发从父布局导航的后导航。

@Override
public void beforeEnter(BeforeEnterEvent event) {
    if (!isAuthenticated()) {
        event.rerouteTo(LoginView.class);
    }
}

您可以在每个视图中实现BeforeEnterprise观察者并一遍又一遍地检查用户是否经过身份验证…或者您可以执行一次:

@SpringComponent
public class AuthenticationControl implements VaadinServiceInitListener {
     @Override
    public void serviceInit(ServiceInitEvent event) {
        event.getSource().addUIInitListener(uiEvent -> {
            final UI ui = uiEvent.getUI();
            ui.addBeforeEnterListener(/* do the check here, either with a method reference or create a separate listener class */);
        });
     }
}