检查客户端区域设置是否在支持的语言列表中。

huangapple go评论109阅读模式
英文:

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(&quot;user_locale&quot;); // 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&lt;Locale&gt; LOCALES = Arrays.asList(new Locale(&quot;en&quot;), new Locale(&quot;de&quot;), new Locale(&quot;fr&quot;), new Locale(&quot;sp&quot;), new Locale(&quot;it&quot;));

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(&quot;BALLROOM_LANGUAGE&quot;);

    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(&quot;/locale&quot;)
public class LocaleController {

    @PostMapping(path = {&quot;&quot;, &quot;/&quot;}, consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE})
    public String locale(@RequestParam(&quot;locale&quot;) String locale,
                         HttpServletRequest request,
                         HttpServletResponse response) {

        if (locale != null &amp;&amp; !locale.isBlank()) {
            LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
            if (localeResolver == null)
                throw new IllegalStateException(&quot;No LocaleResolver found&quot;);

            try {
                localeResolver.setLocale(request, response, StringUtils.parseLocale(locale));
            } catch (IllegalArgumentException e) {
                logger.debug(&quot;Ignoring invalid locale value [{}]: {}&quot;, locale, e.getMessage());
            }
        }

        String referer = request.getHeader(&quot;referer&quot;);
        return referer != null &amp;&amp; !referer.isBlank() ? &quot;redirect:&quot; + referer : &quot;redirect:/&quot;;
    }
}

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(&quot;es&quot;))
    );

    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&lt;String&gt; getGreeting() {
    String msg = messageSourceAccessor.getMessage(&quot;msg&quot;, 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.

huangapple
  • 本文由 发表于 2023年8月4日 23:08:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/76837166.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定