情况:我有一个vaadin-spring应用程序,必须让用户在登录时更改语言。我在登录页面上使用组合框在区域设置之间进行切换。春季语言环境解析器实现是CookieLocaleResolver,因为我想将下次访问的选定选项存储在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;
}
视图:
@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());
});
// ...
}
更改组合框会将名为区域设置的cookie设置为所需的语言区域设置(例如de_DE)。语言环境解析器中的默认语言是de_DE。在登录时,我可以在两个选项之间切换:de_DE和en_US。
vaadin视图中的标题和文本翻译由spring messageSource完成:
someCompoenent.setCaption(messageSource.getMessage("someComponent.caption", args, LocaleContextHolder.getLocale()));
在Vaadin UI中,我调用以下命令在会话和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);
// ...
}
}
我的问题是:当我在登录页面上的语言组合框中选择de_DE语言环境并登录时,LocaleContextHolder.getLocale()返回en_US且UI为英语。但是,如果在浏览器中按F5键并刷新页面,则UI变为de_DE。
为什么?
注意:在登录之前和登录之后,我注意到JSESSONID cookie发生了变化。我不知道在存在区域设置cookie的情况下解析区域设置是否重要,登录前后是否相同。
最佳答案
问题在于,过滤器链中有一个RequestContextFilter,它用每个请求中的默认值覆盖localeResolver解析的语言环境。
快速的解决方案是在消息服务中手动解析语言环境:
Locale locale = localeResolver.resolveLocale(SpringVaadinServletRequest.getCurrent());
并使用此语言环境进行翻译。