英文:
Checking whether client locale is in the list of supported languages
问题
I want to present the website to the users in their preferred language in the case that the website supports that language.
In Spring Boot, I use the following bean to set the default language for the client:
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver localeResolver = new SessionLocaleResolver();
localeResolver.setLocaleAttributeName("user_locale"); // Not strictly needed
localeResolver.setDefaultLocale(Locale.ENGLISH);
return localeResolver;
}
How could I modify it to take the client's language, and check whether it is in the list of supported languages, e.g.
private List<Locale> LOCALES = Arrays.asList(new Locale("en"), new Locale("de"), new Locale("fr"), new Locale("sp"), new Locale("it"));
and then set the locale using something like
return locales.contains(locale) ? locale : Locale.ENGLISH;
Notice that this should happen every time a session is initiated.
英文:
I want to present the website to the users in their preferred language in the case that the website supports that language.
In Spring Boot, I use the following bean to set the default language for the client:
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver localeResolver = new SessionLocaleResolver();
localeResolver.setLocaleAttributeName("user_locale"); // Not strictly needed
localeResolver.setDefaultLocale(Locale.ENGLISH);
return localeResolver;
}
How could I modify it to take the client's language, and check whether it is in the list of supported languages, e.g.
private List<Locale> LOCALES = Arrays.asList(new Locale("en"), new Locale("de"), new Locale("fr"), new Locale("sp"), new Locale("it"));
and then set the locale using something like
return locales.contains(locale) ? locale : Locale.ENGLISH;
Notice that this should happen every time a session is initiated.
答案1
得分: 1
以下是翻译的代码部分:
您可以像这样检索当前存储的区域设置:
Locale locale = LocaleContextHolder.getLocale();
localeResolver.setDefaultLocale(locale);
一个好的方法,如果允许使用cookie,可以像这样实现:
@Bean
public LocaleResolver localeResolver() {
CookieLocaleResolver localeResolver = new CookieLocaleResolver("BALLROOM_LANGUAGE");
Locale locale = LocaleContextHolder.getLocale();
localeResolver.setDefaultLocale(locale);
return localeResolver;
}
无需检查自动请求的客户端语言是否在您的列表中,因为它总是会回退到默认的消息实现(在您的情况下将是英语)。
让用户手动更改区域设置的一种方法(这应该始终是可能的)是创建一个自定义的LocaleController:
@Controller
@RequestMapping("/locale")
public class LocaleController {
@PostMapping(path = {"", "/"}, consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE})
public String locale(@RequestParam("locale") String locale,
HttpServletRequest request,
HttpServletResponse response) {
if (locale != null && !locale.isBlank()) {
LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
if (localeResolver == null)
throw new IllegalStateException("No LocaleResolver found");
try {
localeResolver.setLocale(request, response, StringUtils.parseLocale(locale));
} catch (IllegalArgumentException e) {
logger.debug("Ignoring invalid locale value [{}]: {}", locale, e.getMessage());
}
}
String referer = request.getHeader("referer");
return referer != null && !referer.isBlank() ? "redirect:" + referer : "redirect:/";
}
}
您只需发送一个包含所需区域设置的字符串的POST请求,例如 en_US
。
英文:
You can retrieve the currently stored Locale like this:
Locale locale = LocaleContextHolder.getLocale();
localeResolver.setDefaultLocale(locale);
A good way, if cookies are allowed, would be to implement it like that:
@Bean
public LocaleResolver localeResolver() {
CookieLocaleResolver localeResolver = new CookieLocaleResolver("BALLROOM_LANGUAGE");
Locale locale = LocaleContextHolder.getLocale();
localeResolver.setDefaultLocale(locale);
return localeResolver;
}
There is no need to check whether the automatically requested clients language is in your list, since it would always fallback to your default message implementation (which in your case would be english).
One way to let the user change the locale manually (what should always be possible) would be a custom LocaleController:
@Controller
@RequestMapping("/locale")
public class LocaleController {
@PostMapping(path = {"", "/"}, consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE})
public String locale(@RequestParam("locale") String locale,
HttpServletRequest request,
HttpServletResponse response) {
if (locale != null && !locale.isBlank()) {
LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
if (localeResolver == null)
throw new IllegalStateException("No LocaleResolver found");
try {
localeResolver.setLocale(request, response, StringUtils.parseLocale(locale));
} catch (IllegalArgumentException e) {
logger.debug("Ignoring invalid locale value [{}]: {}", locale, e.getMessage());
}
}
String referer = request.getHeader("referer");
return referer != null && !referer.isBlank() ? "redirect:" + referer : "redirect:/";
}
}
You would simply send a post request containing the desired locale as String in form of e.g. en_US
.
答案2
得分: 1
如果您想根据HTTP标头Accept-Language
更改区域设置,您需要使用AcceptHeaderLocaleResolver
,例如:
@Bean
public LocaleResolver localeResolver() {
var resolver = new AcceptHeaderLocaleResolver();
resolver.setDefaultLocale(Locale.ENGLISH);
resolver.setSupportedLocales(
List.of(Locale.ENGLISH,
Locale.FRENCH,
Locale.of("es"))
);
return resolver;
}
设置很容易,我想这正是您想要的。
下一步是确切地获取使用AcceptHeaderLocaleResolver
定义的区域设置,并使用它,例如,从消息源获取消息。为此,您可以使用LocaleContextHolder
,如下所示:
@Autowired
private MessageSourceAccessor messageSourceAccessor;
@GetMapping(produces = MediaType.TEXT_PLAIN_VALUE)
public ResponseEntity<String> getGreeting() {
String msg = messageSourceAccessor.getMessage("msg", LocaleContextHolder.getLocale());
return ResponseEntity.ok(msg);
}
您可以访问我的 github,我在那里创建了一个可运行的示例。为了测试区域设置,我使用了 Locale Switcher Chrome Extension。
英文:
If you want to change the locale depending on the HTTP header Accept-Language
you need to use AcceptHeaderLocaleResolver
, for example:
@Bean
public LocaleResolver localeResolver() {
var resolver = new AcceptHeaderLocaleResolver();
resolver.setDefaultLocale(Locale.ENGLISH);
resolver.setSupportedLocales(
List.of(Locale.ENGLISH,
Locale.FRENCH,
Locale.of("es"))
);
return resolver;
}
It's easy to set up and I guess that's exatly what you want.
The next step is to get exatly the locale that is defined using AcceptHeaderLocaleResolver
and use it, for example, to get a message from the message sources. To do this you can use LocaleContextHolder
as follows:
@Autowired
private MessageSourceAccessor messageSourceAccessor;
@GetMapping(produces = MediaType.TEXT_PLAIN_VALUE)
public ResponseEntity<String> getGreeting() {
String msg = messageSourceAccessor.getMessage("msg", LocaleContextHolder.getLocale());
return ResponseEntity.ok(msg);
}
}
You can visit my github where I created a working example. To test the locale I used the Locale Switcher Chrome Extension.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论