Skip to content

Commit dc843ad

Browse files
committed
Improve docs on {@code Accept-Language} negotiation
Closes spring-projectsgh-28673
1 parent 9fcafd2 commit dc843ad

File tree

2 files changed

+53
-23
lines changed

2 files changed

+53
-23
lines changed

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

+25-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -29,9 +29,12 @@
2929
import org.springframework.web.server.ServerWebExchange;
3030

3131
/**
32-
* {@link LocaleContextResolver} implementation that simply uses the primary locale
33-
* specified in the "Accept-Language" header of the HTTP request (that is,
34-
* the locale sent by the client browser, normally that of the client's OS).
32+
* {@link LocaleContextResolver} implementation that looks for a match between
33+
* locales in the {@code Accept-Language} header and a list of configured
34+
* supported locales.
35+
*
36+
* <p>See {@link #setSupportedLocales(List)} for further details on how
37+
* supported and requested locales are matched.
3538
*
3639
* <p>Note: Does not support {@link #setLocaleContext}, since the accept header
3740
* can only be changed through changing the client's locale settings.
@@ -50,8 +53,20 @@ public class AcceptHeaderLocaleContextResolver implements LocaleContextResolver
5053

5154

5255
/**
53-
* Configure supported locales to check against the requested locales
54-
* determined via {@link HttpHeaders#getAcceptLanguageAsLocales()}.
56+
* Configure the list of supported locales to compare and match against
57+
* {@link HttpHeaders#getAcceptLanguageAsLocales() requested locales}.
58+
* <p>In order for a supported locale to be considered a match, it must match
59+
* on both country and language. If you want to support a language-only match
60+
* as a fallback, you must configure the language explicitly as a supported
61+
* locale.
62+
* <p>For example, if the supported locales are {@code ["de-DE","en-US"]},
63+
* then a request for {@code "en-GB"} will not match, and neither will a
64+
* request for {@code "en"}. If you want to support additional locales for a
65+
* given language such as {@code "en"}, then you must add it to the list of
66+
* supported locales.
67+
* <p>If there is no match, then the {@link #setDefaultLocale(Locale)
68+
* defaultLocale} is used, if configured, or otherwise falling back on
69+
* the first requested locale.
5570
* @param locales the supported locales
5671
*/
5772
public void setSupportedLocales(List<Locale> locales) {
@@ -117,10 +132,10 @@ private Locale resolveSupportedLocale(@Nullable List<Locale> requestLocales) {
117132
}
118133
else if (languageMatch == null) {
119134
// Let's try to find a language-only match as a fallback
120-
for (Locale candidate : supportedLocales) {
121-
if (!StringUtils.hasLength(candidate.getCountry()) &&
122-
candidate.getLanguage().equals(locale.getLanguage())) {
123-
languageMatch = candidate;
135+
for (Locale supportedLocale : supportedLocales) {
136+
if (!StringUtils.hasLength(supportedLocale.getCountry()) &&
137+
supportedLocale.getLanguage().equals(locale.getLanguage())) {
138+
languageMatch = supportedLocale;
124139
break;
125140
}
126141
}

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

+28-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -29,12 +29,16 @@
2929
import org.springframework.web.servlet.LocaleResolver;
3030

3131
/**
32-
* {@link LocaleResolver} implementation that simply uses the primary locale
33-
* specified in the {@code Accept-Language} header of the HTTP request (that is,
34-
* the locale sent by the client browser, normally that of the client's OS).
32+
* {@link LocaleResolver} implementation that looks for a match between locales
33+
* in the {@code Accept-Language} header and a list of configured supported
34+
* locales.
3535
*
36-
* <p>Note: Does not support {@link #setLocale} since the {@code Accept-Language}
37-
* header can only be changed by changing the client's locale settings.
36+
* <p>See {@link #setSupportedLocales(List)} for further details on how
37+
* supported and requested locales are matched.
38+
*
39+
* <p>Note: This implementation does not support {@link #setLocale} since the
40+
* {@code Accept-Language} header can only be changed by changing the client's
41+
* locale settings.
3842
*
3943
* @author Juergen Hoeller
4044
* @author Rossen Stoyanchev
@@ -47,9 +51,20 @@ public class AcceptHeaderLocaleResolver extends AbstractLocaleResolver {
4751

4852

4953
/**
50-
* Configure supported locales to check against the requested locales
51-
* determined via {@link HttpServletRequest#getLocales()}. If this is not
52-
* configured then {@link HttpServletRequest#getLocale()} is used instead.
54+
* Configure the list of supported locales to compare and match against
55+
* {@link HttpServletRequest#getLocales() requested locales}.
56+
* <p>In order for a supported locale to be considered a match, it must match
57+
* on both country and language. If you want to support a language-only match
58+
* as a fallback, you must configure the language explicitly as a supported
59+
* locale.
60+
* <p>For example, if the supported locales are {@code ["de-DE","en-US"]},
61+
* then a request for {@code "en-GB"} will not match, and neither will a
62+
* request for {@code "en"}. If you want to support additional locales for a
63+
* given language such as {@code "en"}, then you must add it to the list of
64+
* supported locales.
65+
* <p>If there is no match, then the {@link #setDefaultLocale(Locale)
66+
* defaultLocale} is used, if configured, or otherwise falling back on
67+
* {@link HttpServletRequest#getLocale()}.
5368
* @param locales the supported locales
5469
* @since 4.3
5570
*/
@@ -99,10 +114,10 @@ private Locale findSupportedLocale(HttpServletRequest request, List<Locale> supp
99114
}
100115
else if (languageMatch == null) {
101116
// Let's try to find a language-only match as a fallback
102-
for (Locale candidate : supportedLocales) {
103-
if (!StringUtils.hasLength(candidate.getCountry()) &&
104-
candidate.getLanguage().equals(locale.getLanguage())) {
105-
languageMatch = candidate;
117+
for (Locale supportedLocale : supportedLocales) {
118+
if (!StringUtils.hasLength(supportedLocale.getCountry()) &&
119+
supportedLocale.getLanguage().equals(locale.getLanguage())) {
120+
languageMatch = supportedLocale;
106121
break;
107122
}
108123
}

0 commit comments

Comments
 (0)