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

Ste*_*ier 1 vaadin vaadin-flow vaadin14

例如,让我们有:

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

如果用户尚未登录,这将因 NPE 而失败,因为从会话中获取用户将为空。现在我可以在之前添加一个空检查,if(user.isCheckSomething())但理想情况下AppLayout,如果用户未登录,我宁愿根本不进行渲染。 那是我宁愿BeforeEnterObserverpublic void beforeEnter(BeforeEnterEvent event)方法中的视图中失败,但是AppLayout之前调用并创建了该beforeEnter(...)方法被调用。

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

Haw*_*awk 5

根据经验,以任何方式在构造函数中使用 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());
    }
Run Code Online (Sandbox Code Playgroud)

因此,在 beforeEnter 方法中,您将重新路由以登录,否则将触发来自父布局的 after 导航。

@Override
public void beforeEnter(BeforeEnterEvent event) {
    if (!isAuthenticated()) {
        event.rerouteTo(LoginView.class);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

@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 */);
        });
     }
}
Run Code Online (Sandbox Code Playgroud)