Allow locale to be overridden by "Accept-Language"
Previously, when `spring.mvc.locale` was specified, that locale was used regardless of the client's preferences. This commit adds an extra `spring.mvc.locale-resolver` property that can control how the locale is resolved. The default is `ACCEPT_HEADER` but can be set to `FIXED` to restore the previous behaviour. Closes gh-6083
This commit is contained in:
parent
7a5880c900
commit
d54474b81c
|
@ -82,6 +82,7 @@ import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
|||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
|
||||
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
|
||||
import org.springframework.web.servlet.i18n.FixedLocaleResolver;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
|
||||
|
@ -103,6 +104,7 @@ import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
|||
* @author Andy Wilkinson
|
||||
* @author Sébastien Deleuze
|
||||
* @author Eddú Meléndez
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnWebApplication
|
||||
|
@ -224,7 +226,14 @@ public class WebMvcAutoConfiguration {
|
|||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty(prefix = "spring.mvc", name = "locale")
|
||||
public LocaleResolver localeResolver() {
|
||||
return new FixedLocaleResolver(this.mvcProperties.getLocale());
|
||||
if (this.mvcProperties.getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) {
|
||||
return new FixedLocaleResolver(this.mvcProperties.getLocale());
|
||||
}
|
||||
else {
|
||||
AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
|
||||
localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
|
||||
return localeResolver;
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
|
|
@ -42,10 +42,15 @@ public class WebMvcProperties {
|
|||
private DefaultMessageCodesResolver.Format messageCodesResolverFormat;
|
||||
|
||||
/**
|
||||
* Locale to use.
|
||||
* Locale to use. By default, this locale is overridden by the "Accept-Language" header.
|
||||
*/
|
||||
private Locale locale;
|
||||
|
||||
/**
|
||||
* Define how the locale should be resolved.
|
||||
*/
|
||||
private LocaleResolver localeResolver = LocaleResolver.ACCEPT_HEADER;
|
||||
|
||||
/**
|
||||
* Date format to use (e.g. dd/MM/yyyy).
|
||||
*/
|
||||
|
@ -105,6 +110,14 @@ public class WebMvcProperties {
|
|||
this.locale = locale;
|
||||
}
|
||||
|
||||
public LocaleResolver getLocaleResolver() {
|
||||
return this.localeResolver;
|
||||
}
|
||||
|
||||
public void setLocaleResolver(LocaleResolver localeResolver) {
|
||||
this.localeResolver = localeResolver;
|
||||
}
|
||||
|
||||
public String getDateFormat() {
|
||||
return this.dateFormat;
|
||||
}
|
||||
|
@ -240,4 +253,19 @@ public class WebMvcProperties {
|
|||
|
||||
}
|
||||
|
||||
public enum LocaleResolver {
|
||||
|
||||
/**
|
||||
* Always use the configured locale.
|
||||
*/
|
||||
FIXED,
|
||||
|
||||
/**
|
||||
* Use the "Accept-Language" header or the configured locale if the header
|
||||
* is not set.
|
||||
*/
|
||||
ACCEPT_HEADER
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ import org.springframework.context.annotation.Import;
|
|||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.format.support.FormattingConversionService;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
@ -64,6 +65,7 @@ import org.springframework.web.servlet.ViewResolver;
|
|||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
|
||||
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
|
||||
import org.springframework.web.servlet.i18n.FixedLocaleResolver;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||
|
@ -258,14 +260,42 @@ public class WebMvcAutoConfigurationTests {
|
|||
|
||||
@Test
|
||||
public void overrideLocale() throws Exception {
|
||||
load(AllResources.class, "spring.mvc.locale:en_UK",
|
||||
"spring.mvc.locale-resolver=fixed");
|
||||
// mock request and set user preferred locale
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.addPreferredLocale(StringUtils.parseLocaleString("nl_NL"));
|
||||
request.addHeader(HttpHeaders.ACCEPT_LANGUAGE, "nl_NL");
|
||||
LocaleResolver localeResolver = this.context.getBean(LocaleResolver.class);
|
||||
assertThat(localeResolver).isInstanceOf(FixedLocaleResolver.class);
|
||||
Locale locale = localeResolver.resolveLocale(request);
|
||||
// test locale resolver uses fixed locale and not user preferred locale
|
||||
assertThat(locale.toString()).isEqualTo("en_UK");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void useAcceptHeaderLocale() {
|
||||
load(AllResources.class, "spring.mvc.locale:en_UK");
|
||||
// mock request and set user preferred locale
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.addPreferredLocale(StringUtils.parseLocaleString("nl_NL"));
|
||||
request.addHeader(HttpHeaders.ACCEPT_LANGUAGE, "nl_NL");
|
||||
LocaleResolver localeResolver = this.context.getBean(LocaleResolver.class);
|
||||
assertThat(localeResolver).isInstanceOf(AcceptHeaderLocaleResolver.class);
|
||||
Locale locale = localeResolver.resolveLocale(request);
|
||||
assertThat(localeResolver).isInstanceOf(FixedLocaleResolver.class);
|
||||
// test locale resolver uses fixed locale and not user preferred locale
|
||||
// test locale resolver uses user preferred locale
|
||||
assertThat(locale.toString()).isEqualTo("nl_NL");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void useDefaultLocaleIfAcceptHeaderNoSet() {
|
||||
load(AllResources.class, "spring.mvc.locale:en_UK");
|
||||
// mock request and set user preferred locale
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
LocaleResolver localeResolver = this.context.getBean(LocaleResolver.class);
|
||||
assertThat(localeResolver).isInstanceOf(AcceptHeaderLocaleResolver.class);
|
||||
Locale locale = localeResolver.resolveLocale(request);
|
||||
// test locale resolver uses default locale if no header is set
|
||||
assertThat(locale.toString()).isEqualTo("en_UK");
|
||||
}
|
||||
|
||||
|
|
|
@ -336,7 +336,8 @@ content into your application; rather pick only the properties that you need.
|
|||
spring.mvc.dispatch-options-request=false # Dispatch OPTIONS requests to the FrameworkServlet doService method.
|
||||
spring.mvc.favicon.enabled=true # Enable resolution of favicon.ico.
|
||||
spring.mvc.ignore-default-model-on-redirect=true # If the content of the "default" model should be ignored during redirect scenarios.
|
||||
spring.mvc.locale= # Locale to use.
|
||||
spring.mvc.locale= # Locale to use. By default, this locale is overridden by the "Accept-Language" header.
|
||||
spring.mvc.locale-resolver=accept-header # Define how the locale should be resolved.
|
||||
spring.mvc.media-types.*= # Maps file extensions to media types for content negotiation.
|
||||
spring.mvc.message-codes-resolver-format= # Formatting strategy for message codes. For instance `PREFIX_ERROR_CODE`.
|
||||
spring.mvc.servlet.load-on-startup=-1 # Load on startup priority of the Spring Web Services servlet.
|
||||
|
|
Loading…
Reference in New Issue