Browse Source

Improve docs on {@code Accept-Language} negotiation

Closes gh-28673
pull/29969/head
rstoyanchev 2 years ago
parent
commit
dc843adb45
  1. 35
      spring-web/src/main/java/org/springframework/web/server/i18n/AcceptHeaderLocaleContextResolver.java
  2. 41
      spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AcceptHeaderLocaleResolver.java

35
spring-web/src/main/java/org/springframework/web/server/i18n/AcceptHeaderLocaleContextResolver.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2020 the original author or authors. * Copyright 2002-2023 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -29,9 +29,12 @@ import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
/** /**
* {@link LocaleContextResolver} implementation that simply uses the primary locale * {@link LocaleContextResolver} implementation that looks for a match between
* specified in the "Accept-Language" header of the HTTP request (that is, * locales in the {@code Accept-Language} header and a list of configured
* the locale sent by the client browser, normally that of the client's OS). * supported locales.
*
* <p>See {@link #setSupportedLocales(List)} for further details on how
* supported and requested locales are matched.
* *
* <p>Note: Does not support {@link #setLocaleContext}, since the accept header * <p>Note: Does not support {@link #setLocaleContext}, since the accept header
* can only be changed through changing the client's locale settings. * can only be changed through changing the client's locale settings.
@ -50,8 +53,20 @@ public class AcceptHeaderLocaleContextResolver implements LocaleContextResolver
/** /**
* Configure supported locales to check against the requested locales * Configure the list of supported locales to compare and match against
* determined via {@link HttpHeaders#getAcceptLanguageAsLocales()}. * {@link HttpHeaders#getAcceptLanguageAsLocales() requested locales}.
* <p>In order for a supported locale to be considered a match, it must match
* on both country and language. If you want to support a language-only match
* as a fallback, you must configure the language explicitly as a supported
* locale.
* <p>For example, if the supported locales are {@code ["de-DE","en-US"]},
* then a request for {@code "en-GB"} will not match, and neither will a
* request for {@code "en"}. If you want to support additional locales for a
* given language such as {@code "en"}, then you must add it to the list of
* supported locales.
* <p>If there is no match, then the {@link #setDefaultLocale(Locale)
* defaultLocale} is used, if configured, or otherwise falling back on
* the first requested locale.
* @param locales the supported locales * @param locales the supported locales
*/ */
public void setSupportedLocales(List<Locale> locales) { public void setSupportedLocales(List<Locale> locales) {
@ -117,10 +132,10 @@ public class AcceptHeaderLocaleContextResolver implements LocaleContextResolver
} }
else if (languageMatch == null) { else if (languageMatch == null) {
// Let's try to find a language-only match as a fallback // Let's try to find a language-only match as a fallback
for (Locale candidate : supportedLocales) { for (Locale supportedLocale : supportedLocales) {
if (!StringUtils.hasLength(candidate.getCountry()) && if (!StringUtils.hasLength(supportedLocale.getCountry()) &&
candidate.getLanguage().equals(locale.getLanguage())) { supportedLocale.getLanguage().equals(locale.getLanguage())) {
languageMatch = candidate; languageMatch = supportedLocale;
break; break;
} }
} }

41
spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AcceptHeaderLocaleResolver.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2022 the original author or authors. * Copyright 2002-2023 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -29,12 +29,16 @@ import org.springframework.util.StringUtils;
import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.LocaleResolver;
/** /**
* {@link LocaleResolver} implementation that simply uses the primary locale * {@link LocaleResolver} implementation that looks for a match between locales
* specified in the {@code Accept-Language} header of the HTTP request (that is, * in the {@code Accept-Language} header and a list of configured supported
* the locale sent by the client browser, normally that of the client's OS). * locales.
* *
* <p>Note: Does not support {@link #setLocale} since the {@code Accept-Language} * <p>See {@link #setSupportedLocales(List)} for further details on how
* header can only be changed by changing the client's locale settings. * supported and requested locales are matched.
*
* <p>Note: This implementation does not support {@link #setLocale} since the
* {@code Accept-Language} header can only be changed by changing the client's
* locale settings.
* *
* @author Juergen Hoeller * @author Juergen Hoeller
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
@ -47,9 +51,20 @@ public class AcceptHeaderLocaleResolver extends AbstractLocaleResolver {
/** /**
* Configure supported locales to check against the requested locales * Configure the list of supported locales to compare and match against
* determined via {@link HttpServletRequest#getLocales()}. If this is not * {@link HttpServletRequest#getLocales() requested locales}.
* configured then {@link HttpServletRequest#getLocale()} is used instead. * <p>In order for a supported locale to be considered a match, it must match
* on both country and language. If you want to support a language-only match
* as a fallback, you must configure the language explicitly as a supported
* locale.
* <p>For example, if the supported locales are {@code ["de-DE","en-US"]},
* then a request for {@code "en-GB"} will not match, and neither will a
* request for {@code "en"}. If you want to support additional locales for a
* given language such as {@code "en"}, then you must add it to the list of
* supported locales.
* <p>If there is no match, then the {@link #setDefaultLocale(Locale)
* defaultLocale} is used, if configured, or otherwise falling back on
* {@link HttpServletRequest#getLocale()}.
* @param locales the supported locales * @param locales the supported locales
* @since 4.3 * @since 4.3
*/ */
@ -99,10 +114,10 @@ public class AcceptHeaderLocaleResolver extends AbstractLocaleResolver {
} }
else if (languageMatch == null) { else if (languageMatch == null) {
// Let's try to find a language-only match as a fallback // Let's try to find a language-only match as a fallback
for (Locale candidate : supportedLocales) { for (Locale supportedLocale : supportedLocales) {
if (!StringUtils.hasLength(candidate.getCountry()) && if (!StringUtils.hasLength(supportedLocale.getCountry()) &&
candidate.getLanguage().equals(locale.getLanguage())) { supportedLocale.getLanguage().equals(locale.getLanguage())) {
languageMatch = candidate; languageMatch = supportedLocale;
break; break;
} }
} }

Loading…
Cancel
Save