Triggering LocaleChangeEvent correctly

I am trying to test my Vaadin views for correct I18N behaviour. They implement LocaleChangeObserver and are setting the component labels based on the locale in the event. In Firefox i am using the Language Switch extension to easily change between languages for testing.

The behaviour that i am seeing is that, even though upon language change Firefox is sending a different Accept-Language header, The LocaleChangeEvent does not contain the new language but the old one, set when the session was first established. When i clear the session cookie the correct language is loaded.

Is this expected behaviour, and should i detect this language change myself somehow and do UI.getCurrent().setLocale(...) ?

The locale sent by the browser is only once checked, changing the header afterwards does not affect the application as far as I know

That’s indeed the behaviour i’m seeing. I really wonder the idiomatic Vaadin way to handle this. Sure, with a language dropdown somewhere it would be easy.

But based only on the Accept-Language header there does not seem to be a mechanism to handle this.

Correct the drop-down is the way to go, with the default value based on the first accept header it has gotten

Agreed. Anyway, this does seem to work by just looking at the header:

@Component
public class LocaleInitializer implements VaadinServiceInitListener {
  @Override
  public void serviceInit(ServiceInitEvent event) {
    event.getSource().addSessionInitListener(this::sessionInit);
  }

  private void sessionInit(SessionInitEvent event) {
    event.getSession().addRequestHandler(new LocaleRequestHandler());
  }
}
public class LocaleRequestHandler implements RequestHandler {
  @Override
  public boolean handleRequest(
      VaadinSession session, VaadinRequest request, VaadinResponse response) throws IOException {
    Locale requestLocale = request.getLocale();
    session.lock();
    try {
      if (requestLocale != null && !requestLocale.equals(session.getLocale())) {
        session.setLocale(requestLocale);
      }
    } finally {
      session.unlock();
    }
    return false; // Return false to let other request handlers do their job
  }
}

This works, but also adds additional overhead to your application