springvaadinvaadin8vaadin4spring

Why does spring-vaadin forgets my set locale, but suddenly remembers it after a page refresh?


Situation: I have a vaadin-spring application in which I have to let the user change the language at login. I use a combo box at the login page to switch between locales. The spring locale resolver implementation is CookieLocaleResolver because I'd like to store the selected option for the next visit in a cookie.

@Bean
public LocaleResolver localeResolver() {
    CookieLocaleResolver localeResolver = new CookieLocaleResolver();
    localeResolver.setDefaultLocale(new Locale("de", "DE"));
    localeResolver.setCookieName("locale");
    localeResolver.setCookieMaxAge( 60 * 60 * 24 * 31);
    return localeResolver;
}

View:

@SpringView(name = "login")
public class LoginView implements View {
    @Autowired
    private HttpServletRequest request;

    @Autowired
    private HttpServletResponse response;

    @Autowired
    private LocaleResolver localeResolver;

    ComboBox<LanguageOption> languageField;
    // ...
    languageField.addValueChangeListener(option -> {
        localeResolver.setLocale(request, response, option.getValue().getLocale());
    });
    // ...
}

Changing the combobox sets a cookie called locale to the desired language locale (for example de_DE). The default language in the locale resolver is de_DE. At the login, I can change between two options: de_DE and en_US.

The caption and text translation in the vaadin views is done by spring messageSource:

someCompoenent.setCaption(messageSource.getMessage("someComponent.caption", args, LocaleContextHolder.getLocale()));

In the Vaadin UI, I call the following to set the locale on the session and on the UI:

public class MyUI extends UI implements ViewDisplay, ViewAccessControl {
    @Autowired
    private HttpServletRequest httpServletRequest;

    // ...
    @Override
    protected void init(VaadinRequest request) {
        // ...
        Locale currentLocale = localeResolver.resolveLocale(httpServletRequest);
        LocaleContextHolder.setLocale(currentLocale);

        setLocale(currentLocale);
        VaadinSession.getCurrent().setLocale(currentLocale);

        // ...
    }

}

My problem is: when I choose the de_DE locale in the language combobox on the login page and I login, the LocaleContextHolder.getLocale() returns en_US and the UI is in english. However, if I hit F5 on the browser and refresh the page, the UI becomes de_DE.

Why?

A note: I noticed that before login and after login the JSESSONID cookie changes. I don't know if it matters in resolving the locale while the locale cookie is present and it's the same before and after login.


Solution

  • The problem was that there is a RequestContextFilter in the filter chain which overwrites the locale resolved by the localeResolver with a default value in every request.

    The quick solution is to resolve the locale manually in the message service:

    Locale locale = localeResolver.resolveLocale(SpringVaadinServletRequest.getCurrent());
    

    And use this locale for translation.