Skip to content

Commit 6e1cac9

Browse files
committed
AcceptHeaderLocaleResolver keeps language match among supported locales
Issue: SPR-16599
1 parent 7cafa67 commit 6e1cac9

File tree

2 files changed

+25
-15
lines changed

2 files changed

+25
-15
lines changed

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

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -97,37 +97,35 @@ public Locale resolveLocale(HttpServletRequest request) {
9797
return defaultLocale;
9898
}
9999
Locale requestLocale = request.getLocale();
100-
if (isSupportedLocale(requestLocale)) {
100+
List<Locale> supportedLocales = getSupportedLocales();
101+
if (supportedLocales.isEmpty() || supportedLocales.contains(requestLocale)) {
101102
return requestLocale;
102103
}
103-
Locale supportedLocale = findSupportedLocale(request);
104+
Locale supportedLocale = findSupportedLocale(request, supportedLocales);
104105
if (supportedLocale != null) {
105106
return supportedLocale;
106107
}
107108
return (defaultLocale != null ? defaultLocale : requestLocale);
108109
}
109110

110-
private boolean isSupportedLocale(Locale locale) {
111-
List<Locale> supportedLocales = getSupportedLocales();
112-
return (supportedLocales.isEmpty() || supportedLocales.contains(locale));
113-
}
114-
115-
private Locale findSupportedLocale(HttpServletRequest request) {
111+
private Locale findSupportedLocale(HttpServletRequest request, List<Locale> supportedLocales) {
116112
Enumeration<Locale> requestLocales = request.getLocales();
117-
List<Locale> supported = getSupportedLocales();
118113
Locale languageMatch = null;
119114
while (requestLocales.hasMoreElements()) {
120115
Locale locale = requestLocales.nextElement();
121-
if (supported.contains(locale)) {
122-
// Full match: typically language + country
123-
return locale;
116+
if (supportedLocales.contains(locale)) {
117+
if (languageMatch == null || languageMatch.getLanguage().equals(locale.getLanguage())) {
118+
// Full match: language + country, possibly narrowed from earlier language-only match
119+
return locale;
120+
}
124121
}
125122
else if (languageMatch == null) {
126123
// Let's try to find a language-only match as a fallback
127-
for (Locale candidate : supported) {
124+
for (Locale candidate : supportedLocales) {
128125
if (!StringUtils.hasLength(candidate.getCountry()) &&
129126
candidate.getLanguage().equals(locale.getLanguage())) {
130127
languageMatch = candidate;
128+
break;
131129
}
132130
}
133131
}

spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/AcceptHeaderLocaleResolverTests.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,25 @@ public void resolvePreferredAgainstLanguageOnly() {
6363
assertEquals(ENGLISH, this.resolver.resolveLocale(request(GERMANY, US, UK)));
6464
}
6565

66+
@Test
67+
public void resolvePreferredAgainstCountryIfPossible() {
68+
this.resolver.setSupportedLocales(Arrays.asList(ENGLISH, UK));
69+
assertEquals(UK, this.resolver.resolveLocale(request(GERMANY, US, UK)));
70+
}
71+
72+
@Test
73+
public void resolvePreferredAgainstLanguageWithMultipleSupportedLocales() {
74+
this.resolver.setSupportedLocales(Arrays.asList(GERMAN, US));
75+
assertEquals(GERMAN, this.resolver.resolveLocale(request(GERMANY, US, UK)));
76+
}
77+
6678
@Test
6779
public void resolvePreferredNotSupportedWithDefault() {
6880
this.resolver.setSupportedLocales(Arrays.asList(US, JAPAN));
6981
this.resolver.setDefaultLocale(Locale.JAPAN);
7082

7183
MockHttpServletRequest request = new MockHttpServletRequest();
72-
request.addHeader("Accept-Language", KOREA.toString());
84+
request.addHeader("Accept-Language", KOREA.toLanguageTag());
7385
request.setPreferredLocales(Collections.singletonList(KOREA));
7486
assertEquals(Locale.JAPAN, this.resolver.resolveLocale(request));
7587
}
@@ -80,7 +92,7 @@ public void defaultLocale() {
8092
MockHttpServletRequest request = new MockHttpServletRequest();
8193
assertEquals(JAPANESE, this.resolver.resolveLocale(request));
8294

83-
request.addHeader("Accept-Language", US.toString());
95+
request.addHeader("Accept-Language", US.toLanguageTag());
8496
request.setPreferredLocales(Collections.singletonList(US));
8597
assertEquals(US, this.resolver.resolveLocale(request));
8698
}

0 commit comments

Comments
 (0)