Skip to content

Commit 8fda96c

Browse files
committed
AcceptHeaderLocaleResolver falls back to language-only match among its supported locales
Issue: SPR-16457 (cherry picked from commit 4dc9645)
1 parent 9926b68 commit 8fda96c

File tree

2 files changed

+28
-9
lines changed

2 files changed

+28
-9
lines changed

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

+16-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 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.
@@ -23,6 +23,7 @@
2323
import javax.servlet.http.HttpServletRequest;
2424
import javax.servlet.http.HttpServletResponse;
2525

26+
import org.springframework.util.StringUtils;
2627
import org.springframework.web.servlet.LocaleResolver;
2728

2829
/**
@@ -113,13 +114,25 @@ private boolean isSupportedLocale(Locale locale) {
113114

114115
private Locale findSupportedLocale(HttpServletRequest request) {
115116
Enumeration<Locale> requestLocales = request.getLocales();
117+
List<Locale> supported = getSupportedLocales();
118+
Locale languageMatch = null;
116119
while (requestLocales.hasMoreElements()) {
117120
Locale locale = requestLocales.nextElement();
118-
if (getSupportedLocales().contains(locale)) {
121+
if (supported.contains(locale)) {
122+
// Full match: typically language + country
119123
return locale;
120124
}
125+
else if (languageMatch == null) {
126+
// Let's try to find a language-only match as a fallback
127+
for (Locale candidate : supported) {
128+
if (!StringUtils.hasLength(candidate.getCountry()) &&
129+
candidate.getLanguage().equals(locale.getLanguage())) {
130+
languageMatch = candidate;
131+
}
132+
}
133+
}
121134
}
122-
return null;
135+
return languageMatch;
123136
}
124137

125138
@Override

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

+12-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 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.
@@ -36,28 +36,34 @@
3636
*/
3737
public class AcceptHeaderLocaleResolverTests {
3838

39-
private AcceptHeaderLocaleResolver resolver = new AcceptHeaderLocaleResolver();
39+
private final AcceptHeaderLocaleResolver resolver = new AcceptHeaderLocaleResolver();
4040

4141

4242
@Test
43-
public void resolve() throws Exception {
43+
public void resolve() {
4444
assertEquals(CANADA, this.resolver.resolveLocale(request(CANADA)));
4545
assertEquals(US, this.resolver.resolveLocale(request(US, CANADA)));
4646
}
4747

4848
@Test
49-
public void resolvePreferredSupported() throws Exception {
49+
public void resolvePreferredSupported() {
5050
this.resolver.setSupportedLocales(Collections.singletonList(CANADA));
5151
assertEquals(CANADA, this.resolver.resolveLocale(request(US, CANADA)));
5252
}
5353

5454
@Test
55-
public void resolvePreferredNotSupported() throws Exception {
55+
public void resolvePreferredNotSupported() {
5656
this.resolver.setSupportedLocales(Collections.singletonList(CANADA));
5757
assertEquals(US, this.resolver.resolveLocale(request(US, UK)));
5858
}
59+
5960
@Test
61+
public void resolvePreferredAgainstLanguageOnly() {
62+
this.resolver.setSupportedLocales(Collections.singletonList(ENGLISH));
63+
assertEquals(ENGLISH, this.resolver.resolveLocale(request(GERMANY, US, UK)));
64+
}
6065

66+
@Test
6167
public void resolvePreferredNotSupportedWithDefault() {
6268
this.resolver.setSupportedLocales(Arrays.asList(US, JAPAN));
6369
this.resolver.setDefaultLocale(Locale.JAPAN);
@@ -69,7 +75,7 @@ public void resolvePreferredNotSupportedWithDefault() {
6975
}
7076

7177
@Test
72-
public void defaultLocale() throws Exception {
78+
public void defaultLocale() {
7379
this.resolver.setDefaultLocale(JAPANESE);
7480
MockHttpServletRequest request = new MockHttpServletRequest();
7581
assertEquals(JAPANESE, this.resolver.resolveLocale(request));

0 commit comments

Comments
 (0)