How can I do this in v14? I can’t find something similar to Navigator, tried to implement BeforeEnterListener, NavigatorHandler but couldn’t achieve that control over views yet.
on this new proyect in v14, I have a main class, MainLayout and a few others view annotated with @Route(value = “orden”, layout = MainLayout.class), I want to force it to go to the router Login if is not logged yet.
PD: I don’t want to use Spring to handle this
Also tried this but is only triggered when changing between secondary views app/ → app/view1
No matter how I try, every possible way to get an UI instance at this point is null or throws java.lang.IllegalStateException: Cannot access state in VaadinSession or UI without locking the session.
Complete class
public class ApplicationServiceInitListener implements VaadinServiceInitListener {
public ApplicationServiceInitListener() {
System.out.println("Init ApplicationServiceINitListener");
}
@Override
public void serviceInit(ServiceInitEvent event) {
System.out.println("serviceInit...");
event.addRequestHandler((session, request, response) -> {
// UI ui3 = event.getSource().findUI(request); //returns null
// UI ui2 = session.getUIs().iterator().next(); // throws Illegal
UI ui = UI.getCurrent();
ui.addBeforeEnterListener(evt -> {
Location location = evt.getLocation();
if (isLogged()) {
if (location.getPath().equals("login")) {
//si se quiere ir a login, ya logeado, vuelve al inicio
evt.forwardTo("");
Notification.show("Ya te logeaste mono");
}
} else {
if (!location.getPath().equals("login")) {
//if try to skip the login
evt.forwardTo("login");
Notification.show("No te hagas del vivo");
}
}
});
return false;
});
event.getSource().addUIInitListener(evt -> {
System.out.println("UI Init listener");
});
}
You should define the UI-beforeEnterListener in the UIInitListener. In the UIInitEvent you can call event.getUI() to get the ui instance.
public class ApplicationServiceInitListener implements VaadinServiceInitListener {
public ApplicationServiceInitListener() {
System.out.println("Init ApplicationServiceINitListener");
}
@Override
public void serviceInit(ServiceInitEvent event) {
System.out.println("serviceInit...");
event.getSource().addUIInitListener(evt -> {
System.out.println("UI Init listener");
evt.getUI().addBeforeEnterListener(evt -> {
Location location = evt.getLocation();
if (isLogged()) {
if (location.getPath().equals("login")) {
//si se quiere ir a login, ya logeado, vuelve al inicio
evt.forwardTo("");
Notification.show("Ya te logeaste mono");
}
} else {
if (!location.getPath().equals("login")) {
//if try to skip the login
evt.forwardTo("login");
Notification.show("No te hagas del vivo");
}
}
});
});
}
}
I realize you wrote earlier that using a BeforeEnterListener alone only works in some cases for you. I would tackle that issue instead and use this code, because the RequestHandler has no 100%-successful way of getting the current UI instance, because it can be that there is no UI set. The javadoc on the method VaadinService::findUI explains this better:
/**
* Finds the {@link UI} that belongs to the provided request. This is
* generally only supported for UIDL requests as other request types are not
* related to any particular UI or have the UI information encoded in a
* non-standard way. The returned UI is also set as the current UI (
* {@link UI#setCurrent(UI)}).
*
* @param request
* the request for which a UI is desired
* @return the UI belonging to the request or null if no UI is found
*/