How to handle different UIs and their URI parameters?

Hello,

I have following problem:

I want to open different browser windows with different URI parameters. My problem is, that I can not map the request to the right UI.

Example:
URL = localhost:8080/?userName=abc
→ UI will be created for user = abc

URL = localhost:8080/?userName=xyz
→ UI will be created for user = xyz

The RequestHandler is added to the session.

session.addRequestHandler(myRequestHandler);

But in the RequestHandler I can not differ, which browser window (UI) sends the request, so I can not handle the URI parameters correctly only for the one UI, that should listen to it.

public class MyRequestHandler implements RequestHandler {

  private MyUI ui;

  public MyRequestHandler(MyUI ui) {
  this.ui = ui;
  }

  @Override
   public boolean handleRequest(final VaadinSession session, final VaadinRequest request, final VaadinResponse response) throws IOException {
        // Here I would like to make some stuff on my UI
  ui.setUser("...");
        return false;
    }
}

My UI would look like this:

public class MyUI extends UI {
@Override
    protected void init(final VaadinRequest request) {
  MyRequestHandler myRequestHandler = new MyRequestHandler(this);
  getSession().addRequestHandler(myRequestHandler);
  }
}

But the request do not include any informations about the UI (UI_ID). Furthermore, all RequestHandlers are called, when one browser window will be refreshed.

I think, this is a very common problem with web applications. How can I handle different URI requests for different UIs???

Best regards and thanks,
Tino

PS: Of course I do not want to login 2 different users for one HTTP session. This is just a simple example!!! Please do not discuss on that. :wink:

I’m not sure what your actual use case is. If you want to customize the UI instances based on request parameters, just do it in UI.init(). Remember that every time the user loads a page, a new UI instance is created:

class MyUI extends UI {
  @Override
  protected void init(VaadinRequest request) {
    setUser(request.getAttribute("user"));
    // ... 
  }
}

RequestHandlers are a low-level tool with very specific use cases and are usually not relevant to UI-level customization; also adding them in UI.init is almost always wrong, as it’s too late at that point and it’ll add a new instance to the session wherever a UI is loaded, when actually you usually only want one.

If you want to server different UI
subclasses
based on different request URLs, you’ll want to write a UIProvider instead, and use the UIProvider init parameter in your web.xml instead of UI.

Hello Johannes,

thank you very much for your quick reply. It helped me very much.

Your recommendation works great, as long as you do not use the annotation “@PreserveOnRefresh”. So I decided to remove this annotation.

Unfortunately, we are loosing the feature, that a browser refresh only redraws the browser content. (We need this sometimes, because of some browser drawing bugs) Further more, our customers are used to use the reload button in the browser for some reasons. This would result in a new UI, what means, that the user has to log in again.

If you have any suggestion to solve this, too, I would be very happy. :slight_smile:

Best regards and a nice weekend.
Tino

Oh, right. I forgot that a @PreserveOnRefresh UI is still preserved even if you change the URL, as long as the window stays the same. There’s
a ticket
about adding a “reinit” method to UI that’s called when the UI is reloaded - it would be useful in this case as well.

I think opening a new UI shouldn’t necessarily mean that the user needs to login again - the login functionality should be session-based so that only the first UI load in a session requires logging in.