为什么spring-vaadin忘记了我设置的语言环境,但刷新页面后突然想起来了?
Why does spring-vaadin forgets my set locale, but suddenly remembers it after a page refresh?
情况:我有一个 vaadin-spring 应用程序,我必须让用户在登录时更改语言。我在登录页面使用组合框在语言环境之间切换。 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());
});
// ...
}
更改组合框会将名为 locale 的 cookie 设置为所需的语言区域设置(例如 de_DE)。语言环境解析器中的默认语言是 de_DE。在登录时,我可以在两个选项之间切换:de_DE 和 en_US。
vaadin 视图中的标题和文本翻译由 spring messageSource:
完成
someCompoenent.setCaption(messageSource.getMessage("someComponent.caption", args, LocaleContextHolder.getLocale()));
在 Vaadin UI 中,我调用以下命令在 session 和 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() returns en_US 和 UI 是英文的。但是,如果我在浏览器上按 F5 并刷新页面,UI 会变成 de_DE。
为什么?
注:我注意到登录前和登录后 JSESSONID cookie 发生了变化。我不知道在存在区域设置 cookie 时解析区域设置是否重要,并且在登录前后都是一样的。
您的问题是 - 一旦创建了 Vaadin UI
- 您就不会更改 UI
对象的语言环境。您只能在 LocaleResolver
上更改它,这是一个 Spring 组件。在浏览器中按 F5 键刷新页面会创建一个新的 UI
,因此会应用新语言。
我不是 100% 确定,但我认为当您的语言选择发生变化时额外调用 yourUi.setLocale(currentLocale)
无济于事。这是因为像 Label
这样的 Vaadin 组件已经创建并设置了翻译文本。因此,如果您真的想就地更改语言而不重新创建整个 UI
,则必须更新所有 Vaadin 组件以显示新语言的文本。但是,我想这是很大的努力。
我的解决方案是通知用户并重新创建会话:
Page.getCurrent().setLocation("");
VaadinSession.getCurrent().close();
无论如何,当用户第一次访问您的网站时(没有 cookie),浏览器会发送用户的首选语言,Vaadin 将其选为默认语言。这对大多数用户来说已经足够了。
问题是过滤器链中有一个 RequestContextFilter,它会在每个请求中用默认值覆盖 localeResolver 解析的语言环境。
快速解决方案是在消息服务中手动解析语言环境:
Locale locale = localeResolver.resolveLocale(SpringVaadinServletRequest.getCurrent());
并使用此语言环境进行翻译。
情况:我有一个 vaadin-spring 应用程序,我必须让用户在登录时更改语言。我在登录页面使用组合框在语言环境之间切换。 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());
});
// ...
}
更改组合框会将名为 locale 的 cookie 设置为所需的语言区域设置(例如 de_DE)。语言环境解析器中的默认语言是 de_DE。在登录时,我可以在两个选项之间切换:de_DE 和 en_US。
vaadin 视图中的标题和文本翻译由 spring messageSource:
完成someCompoenent.setCaption(messageSource.getMessage("someComponent.caption", args, LocaleContextHolder.getLocale()));
在 Vaadin UI 中,我调用以下命令在 session 和 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() returns en_US 和 UI 是英文的。但是,如果我在浏览器上按 F5 并刷新页面,UI 会变成 de_DE。
为什么?
注:我注意到登录前和登录后 JSESSONID cookie 发生了变化。我不知道在存在区域设置 cookie 时解析区域设置是否重要,并且在登录前后都是一样的。
您的问题是 - 一旦创建了 Vaadin UI
- 您就不会更改 UI
对象的语言环境。您只能在 LocaleResolver
上更改它,这是一个 Spring 组件。在浏览器中按 F5 键刷新页面会创建一个新的 UI
,因此会应用新语言。
我不是 100% 确定,但我认为当您的语言选择发生变化时额外调用 yourUi.setLocale(currentLocale)
无济于事。这是因为像 Label
这样的 Vaadin 组件已经创建并设置了翻译文本。因此,如果您真的想就地更改语言而不重新创建整个 UI
,则必须更新所有 Vaadin 组件以显示新语言的文本。但是,我想这是很大的努力。
我的解决方案是通知用户并重新创建会话:
Page.getCurrent().setLocation("");
VaadinSession.getCurrent().close();
无论如何,当用户第一次访问您的网站时(没有 cookie),浏览器会发送用户的首选语言,Vaadin 将其选为默认语言。这对大多数用户来说已经足够了。
问题是过滤器链中有一个 RequestContextFilter,它会在每个请求中用默认值覆盖 localeResolver 解析的语言环境。
快速解决方案是在消息服务中手动解析语言环境:
Locale locale = localeResolver.resolveLocale(SpringVaadinServletRequest.getCurrent());
并使用此语言环境进行翻译。