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.
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.