From f53c64554b5c0dd8aed16883bb08c42b8611649b Mon Sep 17 00:00:00 2001 From: Vedran Pavic Date: Fri, 30 Sep 2022 15:23:25 +0200 Subject: [PATCH 1/3] AcceptHeaderLocaleResolver implements LocaleContextResolver At present, AcceptHeaderLocaleResolver is the only LocaleResolver implementation that doesn't also implement LocaleContextResolver. This is also not aligned with WebFlux, where the entire resolver hierarchy works with LocaleContext. This commit updates AcceptHeaderLocaleResolver to implement LocaleContextResolver. --- .../i18n/AcceptHeaderLocaleResolver.java | 17 ++++++++------ .../web/servlet/i18n/LocaleResolverTests.java | 23 +++++++++++-------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AcceptHeaderLocaleResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AcceptHeaderLocaleResolver.java index 15e514f28688..1f4dd76e45fb 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AcceptHeaderLocaleResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AcceptHeaderLocaleResolver.java @@ -24,6 +24,8 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import org.springframework.context.i18n.LocaleContext; +import org.springframework.context.i18n.SimpleLocaleContext; import org.springframework.lang.Nullable; import org.springframework.util.StringUtils; import org.springframework.web.servlet.LocaleResolver; @@ -41,7 +43,7 @@ * @since 27.02.2003 * @see jakarta.servlet.http.HttpServletRequest#getLocale() */ -public class AcceptHeaderLocaleResolver extends AbstractLocaleResolver { +public class AcceptHeaderLocaleResolver extends AbstractLocaleContextResolver { private final List supportedLocales = new ArrayList<>(4); @@ -68,21 +70,21 @@ public List getSupportedLocales() { @Override - public Locale resolveLocale(HttpServletRequest request) { + public LocaleContext resolveLocaleContext(HttpServletRequest request) { Locale defaultLocale = getDefaultLocale(); if (defaultLocale != null && request.getHeader("Accept-Language") == null) { - return defaultLocale; + return new SimpleLocaleContext(defaultLocale); } Locale requestLocale = request.getLocale(); List supportedLocales = getSupportedLocales(); if (supportedLocales.isEmpty() || supportedLocales.contains(requestLocale)) { - return requestLocale; + return new SimpleLocaleContext(requestLocale); } Locale supportedLocale = findSupportedLocale(request, supportedLocales); if (supportedLocale != null) { - return supportedLocale; + return new SimpleLocaleContext(supportedLocale); } - return (defaultLocale != null ? defaultLocale : requestLocale); + return new SimpleLocaleContext(defaultLocale != null ? defaultLocale : requestLocale); } @Nullable @@ -112,7 +114,8 @@ else if (languageMatch == null) { } @Override - public void setLocale(HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable Locale locale) { + public void setLocaleContext(HttpServletRequest request, @Nullable HttpServletResponse response, + @Nullable LocaleContext localeContext) { throw new UnsupportedOperationException( "Cannot change HTTP Accept-Language header - use a different locale resolution strategy"); } diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/LocaleResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/LocaleResolverTests.java index 3888670e3209..85d583c25c52 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/LocaleResolverTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/LocaleResolverTests.java @@ -38,31 +38,32 @@ * Unit tests for various {@link LocaleResolver} implementations. * * @author Juergen Hoeller + * @author Vedran Pavic * @since 20.03.2003 */ class LocaleResolverTests { @Test void acceptHeaderLocaleResolver() { - doTest(new AcceptHeaderLocaleResolver(), false); + doTest(new AcceptHeaderLocaleResolver(), false, false); } @Test void fixedLocaleResolver() { - doTest(new FixedLocaleResolver(Locale.UK), false); + doTest(new FixedLocaleResolver(Locale.UK), false, true); } @Test void cookieLocaleResolver() { - doTest(new CookieLocaleResolver(), true); + doTest(new CookieLocaleResolver(), true, true); } @Test void sessionLocaleResolver() { - doTest(new SessionLocaleResolver(), true); + doTest(new SessionLocaleResolver(), true, true); } - private void doTest(LocaleResolver localeResolver, boolean shouldSet) { + private void doTest(LocaleResolver localeResolver, boolean shouldSet, boolean timeZoneAware) { // create mocks MockServletContext context = new MockServletContext(); MockHttpServletRequest request = new MockHttpServletRequest(context); @@ -93,15 +94,19 @@ private void doTest(LocaleResolver localeResolver, boolean shouldSet) { else { assertThat(localeContext.getLocale()).isEqualTo(Locale.UK); } - boolean condition2 = localeContext instanceof TimeZoneAwareLocaleContext; - assertThat(condition2).isTrue(); - assertThat(((TimeZoneAwareLocaleContext) localeContext).getTimeZone()).isNull(); + if (timeZoneAware) { + boolean condition2 = localeContext instanceof TimeZoneAwareLocaleContext; + assertThat(condition2).isTrue(); + assertThat(((TimeZoneAwareLocaleContext) localeContext).getTimeZone()).isNull(); + } if (localeContextResolver instanceof AbstractLocaleContextResolver) { ((AbstractLocaleContextResolver) localeContextResolver).setDefaultTimeZone(TimeZone.getTimeZone("GMT+1")); request.removeAttribute(CookieLocaleResolver.LOCALE_REQUEST_ATTRIBUTE_NAME); localeContextResolver.resolveLocaleContext(request); - assertThat(TimeZone.getTimeZone("GMT+1")).isEqualTo(((TimeZoneAwareLocaleContext) localeContext).getTimeZone()); + if (timeZoneAware) { + assertThat(TimeZone.getTimeZone("GMT+1")).isEqualTo(((TimeZoneAwareLocaleContext) localeContext).getTimeZone()); + } } try { From 0c2f99bebab02e0b70fe5d76558f03ad14f92772 Mon Sep 17 00:00:00 2001 From: Vedran Pavic Date: Fri, 30 Sep 2022 15:24:03 +0200 Subject: [PATCH 2/3] Deprecate AbstractLocaleResolver This commit deprecates AbstractLocaleResolver in favor of AbstractLocaleContextResolver. --- .../i18n/AbstractLocaleContextResolver.java | 23 ++++++++++++++++++- .../servlet/i18n/AbstractLocaleResolver.java | 2 ++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AbstractLocaleContextResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AbstractLocaleContextResolver.java index 0b07bc682f14..17187ae8d7d1 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AbstractLocaleContextResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AbstractLocaleContextResolver.java @@ -16,6 +16,7 @@ package org.springframework.web.servlet.i18n; +import java.util.Locale; import java.util.TimeZone; import org.springframework.lang.Nullable; @@ -32,12 +33,32 @@ * @see #setDefaultLocale * @see #setDefaultTimeZone */ -public abstract class AbstractLocaleContextResolver extends AbstractLocaleResolver implements LocaleContextResolver { +public abstract class AbstractLocaleContextResolver implements LocaleContextResolver { + + @Nullable + private Locale defaultLocale; @Nullable private TimeZone defaultTimeZone; + /** + * Set a default {@link Locale} that this resolver will return if no other + * locale is found. + */ + public void setDefaultLocale(@Nullable Locale defaultLocale) { + this.defaultLocale = defaultLocale; + } + + /** + * Get the default {@link Locale} that this resolver is supposed to fall back + * to, if any. + */ + @Nullable + protected Locale getDefaultLocale() { + return this.defaultLocale; + } + /** * Set a default {@link TimeZone} that this resolver will return if no other * time zone is found. diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AbstractLocaleResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AbstractLocaleResolver.java index c851ed18e065..62a34cb6a7f1 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AbstractLocaleResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AbstractLocaleResolver.java @@ -29,7 +29,9 @@ * @author Juergen Hoeller * @since 1.2.9 * @see #setDefaultLocale + * @deprecated since 6.0 in favor of {@link AbstractLocaleContextResolver} */ +@Deprecated(since = "6.0") public abstract class AbstractLocaleResolver implements LocaleResolver { @Nullable From ea63d2af96fec730fe775c0e0d2113b72a998cb7 Mon Sep 17 00:00:00 2001 From: Vedran Pavic Date: Fri, 30 Sep 2022 18:48:28 +0200 Subject: [PATCH 3/3] Deprecate LocaleResolver This commit deprecates LocaleResolver and updates all references to use LocaleContextResolver instead. --- .../servlet/client/MockMvcWebTestClient.java | 6 +- .../servlet/client/StandaloneMockMvcSpec.java | 4 +- .../setup/StandaloneMockMvcBuilder.java | 6 +- .../web/servlet/DispatcherServlet.java | 29 +++-- .../web/servlet/LocaleContextResolver.java | 3 +- .../web/servlet/LocaleResolver.java | 2 + .../WebMvcConfigurationSupport.java | 4 +- .../handler/DispatcherServletWebRequest.java | 6 +- .../i18n/AcceptHeaderLocaleResolver.java | 6 +- .../servlet/i18n/CookieLocaleResolver.java | 4 +- .../web/servlet/i18n/FixedLocaleResolver.java | 4 +- .../servlet/i18n/LocaleChangeInterceptor.java | 12 +- .../servlet/i18n/SessionLocaleResolver.java | 2 +- .../web/servlet/support/RequestContext.java | 33 +++-- .../servlet/support/RequestContextUtils.java | 28 ++-- .../web/servlet/DispatcherServlet.properties | 4 +- .../web/servlet/config/MvcNamespaceTests.java | 4 +- .../WebMvcConfigurationSupportTests.java | 6 +- .../i18n/AcceptHeaderLocaleResolverTests.java | 20 +-- .../i18n/CookieLocaleResolverTests.java | 96 ++------------ .../web/servlet/i18n/LocaleResolverTests.java | 121 +++++++++--------- .../i18n/SessionLocaleResolverTests.java | 19 +-- .../web/servlet/tags/AbstractTagTests.java | 6 +- src/docs/asciidoc/web/webmvc.adoc | 14 +- 24 files changed, 184 insertions(+), 255 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/client/MockMvcWebTestClient.java b/spring-test/src/main/java/org/springframework/test/web/servlet/client/MockMvcWebTestClient.java index 4a58df0c0c4d..f240da38dbd9 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/client/MockMvcWebTestClient.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/client/MockMvcWebTestClient.java @@ -45,7 +45,7 @@ import org.springframework.web.servlet.FlashMapManager; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.HandlerInterceptor; -import org.springframework.web.servlet.LocaleResolver; +import org.springframework.web.servlet.LocaleContextResolver; import org.springframework.web.servlet.View; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; @@ -335,9 +335,9 @@ ControllerSpec mappedInterceptors( /** * Provide the LocaleResolver to use. *

This is delegated to - * {@link StandaloneMockMvcBuilder#setLocaleResolver(LocaleResolver)}. + * {@link StandaloneMockMvcBuilder#setLocaleResolver(LocaleContextResolver)}. */ - ControllerSpec localeResolver(LocaleResolver localeResolver); + ControllerSpec localeResolver(LocaleContextResolver localeResolver); /** * Provide a custom FlashMapManager. diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/client/StandaloneMockMvcSpec.java b/spring-test/src/main/java/org/springframework/test/web/servlet/client/StandaloneMockMvcSpec.java index b7b1f4d44881..588d3492e113 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/client/StandaloneMockMvcSpec.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/client/StandaloneMockMvcSpec.java @@ -31,7 +31,7 @@ import org.springframework.web.servlet.FlashMapManager; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.HandlerInterceptor; -import org.springframework.web.servlet.LocaleResolver; +import org.springframework.web.servlet.LocaleContextResolver; import org.springframework.web.servlet.View; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; @@ -135,7 +135,7 @@ public StandaloneMockMvcSpec singleView(View view) { } @Override - public StandaloneMockMvcSpec localeResolver(LocaleResolver localeResolver) { + public StandaloneMockMvcSpec localeResolver(LocaleContextResolver localeResolver) { this.mockMvcBuilder.setLocaleResolver(localeResolver); return this; } diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/StandaloneMockMvcBuilder.java b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/StandaloneMockMvcBuilder.java index 2671c5217e14..e3219ff436ea 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/StandaloneMockMvcBuilder.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/StandaloneMockMvcBuilder.java @@ -51,7 +51,7 @@ import org.springframework.web.servlet.FlashMapManager; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.HandlerInterceptor; -import org.springframework.web.servlet.LocaleResolver; +import org.springframework.web.servlet.LocaleContextResolver; import org.springframework.web.servlet.View; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer; @@ -121,7 +121,7 @@ public class StandaloneMockMvcBuilder extends AbstractMockMvcBuilder viewResolvers; - private LocaleResolver localeResolver = new AcceptHeaderLocaleResolver(); + private LocaleContextResolver localeResolver = new AcceptHeaderLocaleResolver(); @Nullable private FlashMapManager flashMapManager; @@ -297,7 +297,7 @@ public StandaloneMockMvcBuilder setSingleView(View view) { * Provide a LocaleResolver instance. * If not provided, the default one used is {@link AcceptHeaderLocaleResolver}. */ - public StandaloneMockMvcBuilder setLocaleResolver(LocaleResolver localeResolver) { + public StandaloneMockMvcBuilder setLocaleResolver(LocaleContextResolver localeResolver) { this.localeResolver = localeResolver; return this; } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java index 1ea651d3b840..8b3d4d6e73ff 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java @@ -120,7 +120,7 @@ * implementation for Servlet 3 is included. The MultipartResolver bean name is * "multipartResolver"; default is none. * - *

  • Its locale resolution strategy is determined by a {@link LocaleResolver}. + *
  • Its locale resolution strategy is determined by a {@link LocaleContextResolver}. * Out-of-the-box implementations work via HTTP accept header, cookie, or session. * The LocaleResolver bean name is "localeResolver"; default is * {@link org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver}. @@ -156,6 +156,7 @@ * @author Chris Beams * @author Rossen Stoyanchev * @author Sebastien Deleuze + * @author Vedran Pavic * @see org.springframework.web.HttpRequestHandler * @see org.springframework.web.servlet.mvc.Controller * @see org.springframework.web.context.ContextLoaderListener @@ -313,9 +314,9 @@ public class DispatcherServlet extends FrameworkServlet { @Nullable private MultipartResolver multipartResolver; - /** LocaleResolver used by this servlet. */ + /** LocaleContextResolver used by this servlet. */ @Nullable - private LocaleResolver localeResolver; + private LocaleContextResolver localeResolver; /** ThemeResolver used by this servlet. */ @Nullable @@ -543,7 +544,7 @@ else if (logger.isDebugEnabled()) { */ private void initLocaleResolver(ApplicationContext context) { try { - this.localeResolver = context.getBean(LOCALE_RESOLVER_BEAN_NAME, LocaleResolver.class); + this.localeResolver = context.getBean(LOCALE_RESOLVER_BEAN_NAME, LocaleContextResolver.class); if (logger.isTraceEnabled()) { logger.trace("Detected " + this.localeResolver); } @@ -553,7 +554,7 @@ else if (logger.isDebugEnabled()) { } catch (NoSuchBeanDefinitionException ex) { // We need to use the default. - this.localeResolver = getDefaultStrategy(context, LocaleResolver.class); + this.localeResolver = getDefaultStrategy(context, LocaleContextResolver.class); if (logger.isTraceEnabled()) { logger.trace("No LocaleResolver '" + LOCALE_RESOLVER_BEAN_NAME + "': using default [" + this.localeResolver.getClass().getSimpleName() + "]"); @@ -1186,13 +1187,8 @@ private void processDispatchResult(HttpServletRequest request, HttpServletRespon */ @Override protected LocaleContext buildLocaleContext(final HttpServletRequest request) { - LocaleResolver lr = this.localeResolver; - if (lr instanceof LocaleContextResolver) { - return ((LocaleContextResolver) lr).resolveLocaleContext(request); - } - else { - return () -> (lr != null ? lr.resolveLocale(request) : request.getLocale()); - } + LocaleContextResolver lr = this.localeResolver; + return (lr != null ? lr.resolveLocaleContext(request) : request::getLocale); } /** @@ -1379,8 +1375,13 @@ else if (logger.isDebugEnabled()) { */ protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception { // Determine locale for request and apply it to the response. - Locale locale = - (this.localeResolver != null ? this.localeResolver.resolveLocale(request) : request.getLocale()); + Locale locale = null; + if (this.localeResolver != null) { + locale = this.localeResolver.resolveLocaleContext(request).getLocale(); + } + if (locale == null) { + locale = request.getLocale(); + } response.setLocale(locale); View view; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/LocaleContextResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/LocaleContextResolver.java index 4331c017f887..aaa783f1c082 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/LocaleContextResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/LocaleContextResolver.java @@ -42,6 +42,7 @@ * @see org.springframework.web.servlet.support.RequestContext#getTimeZone * @see org.springframework.web.servlet.support.RequestContextUtils#getTimeZone */ +@SuppressWarnings("deprecation") public interface LocaleContextResolver extends LocaleResolver { /** @@ -58,7 +59,6 @@ public interface LocaleContextResolver extends LocaleResolver { * the returned context, which again can be accessed through downcasting. * @param request the request to resolve the locale context for * @return the current locale context (never {@code null} - * @see #resolveLocale(HttpServletRequest) * @see org.springframework.web.servlet.support.RequestContextUtils#getLocale * @see org.springframework.web.servlet.support.RequestContextUtils#getTimeZone */ @@ -72,7 +72,6 @@ public interface LocaleContextResolver extends LocaleResolver { * @param localeContext the new locale context, or {@code null} to clear the locale * @throws UnsupportedOperationException if the LocaleResolver implementation * does not support dynamic changing of the locale or time zone - * @see #setLocale(HttpServletRequest, HttpServletResponse, Locale) * @see org.springframework.context.i18n.SimpleLocaleContext * @see org.springframework.context.i18n.SimpleTimeZoneAwareLocaleContext */ diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/LocaleResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/LocaleResolver.java index b4519563d6ee..89010cb111e6 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/LocaleResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/LocaleResolver.java @@ -50,7 +50,9 @@ * @see org.springframework.context.i18n.LocaleContextHolder * @see org.springframework.web.servlet.support.RequestContext#getLocale * @see org.springframework.web.servlet.support.RequestContextUtils#getLocale + * @deprecated since 6.0 in favor of {@link LocaleContextResolver} */ +@Deprecated(since = "6.0") public interface LocaleResolver { /** diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java index 3394b8eed13d..61a1cf0014c1 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java @@ -80,7 +80,7 @@ import org.springframework.web.servlet.HandlerAdapter; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.HandlerMapping; -import org.springframework.web.servlet.LocaleResolver; +import org.springframework.web.servlet.LocaleContextResolver; import org.springframework.web.servlet.RequestToViewNameTranslator; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.function.support.HandlerFunctionAdapter; @@ -1158,7 +1158,7 @@ public HandlerMappingIntrospector mvcHandlerMappingIntrospector() { } @Bean - public LocaleResolver localeResolver() { + public LocaleContextResolver localeResolver() { return new AcceptHeaderLocaleResolver(); } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/DispatcherServletWebRequest.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/DispatcherServletWebRequest.java index cace2a641517..0bdc96d5e98e 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/DispatcherServletWebRequest.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/DispatcherServletWebRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,12 +28,12 @@ * {@link ServletWebRequest} subclass that is aware of * {@link org.springframework.web.servlet.DispatcherServlet}'s * request context, such as the Locale determined by the configured - * {@link org.springframework.web.servlet.LocaleResolver}. + * {@link org.springframework.web.servlet.LocaleContextResolver}. * * @author Juergen Hoeller * @since 2.0 * @see #getLocale() - * @see org.springframework.web.servlet.LocaleResolver + * @see org.springframework.web.servlet.LocaleContextResolver */ public class DispatcherServletWebRequest extends ServletWebRequest { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AcceptHeaderLocaleResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AcceptHeaderLocaleResolver.java index 1f4dd76e45fb..87ba5a59c2a8 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AcceptHeaderLocaleResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AcceptHeaderLocaleResolver.java @@ -28,14 +28,14 @@ import org.springframework.context.i18n.SimpleLocaleContext; import org.springframework.lang.Nullable; import org.springframework.util.StringUtils; -import org.springframework.web.servlet.LocaleResolver; +import org.springframework.web.servlet.LocaleContextResolver; /** - * {@link LocaleResolver} implementation that simply uses the primary locale + * {@link LocaleContextResolver} implementation that simply uses the primary locale * specified in the {@code Accept-Language} header of the HTTP request (that is, * the locale sent by the client browser, normally that of the client's OS). * - *

    Note: Does not support {@link #setLocale} since the {@code Accept-Language} + *

    Note: Does not support {@link #setLocaleContext} since the {@code Accept-Language} * header can only be changed by changing the client's locale settings. * * @author Juergen Hoeller diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/CookieLocaleResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/CookieLocaleResolver.java index dc3dd3acbe27..5d10530828b3 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/CookieLocaleResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/CookieLocaleResolver.java @@ -34,11 +34,11 @@ import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; -import org.springframework.web.servlet.LocaleResolver; +import org.springframework.web.servlet.LocaleContextResolver; import org.springframework.web.util.WebUtils; /** - * {@link LocaleResolver} implementation that uses a cookie sent back to the user + * {@link LocaleContextResolver} implementation that uses a cookie sent back to the user * in case of a custom setting, with a fallback to the configured default locale, * the request's {@code Accept-Language} header, or the default locale for the server. * diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/FixedLocaleResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/FixedLocaleResolver.java index ada77bdcd365..0865d31cf452 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/FixedLocaleResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/FixedLocaleResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,7 +27,7 @@ import org.springframework.lang.Nullable; /** - * {@link org.springframework.web.servlet.LocaleResolver} implementation + * {@link org.springframework.web.servlet.LocaleContextResolver} implementation * that always returns a fixed default locale and optionally time zone. * Default is the current JVM's default locale. * diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/LocaleChangeInterceptor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/LocaleChangeInterceptor.java index 93996c9b946e..5017218bd43b 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/LocaleChangeInterceptor.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/LocaleChangeInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,11 +24,12 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.context.i18n.SimpleLocaleContext; import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; import org.springframework.web.servlet.HandlerInterceptor; -import org.springframework.web.servlet.LocaleResolver; +import org.springframework.web.servlet.LocaleContextResolver; import org.springframework.web.servlet.support.RequestContextUtils; /** @@ -38,7 +39,7 @@ * @author Juergen Hoeller * @author Rossen Stoyanchev * @since 20.06.2003 - * @see org.springframework.web.servlet.LocaleResolver + * @see org.springframework.web.servlet.LocaleContextResolver */ public class LocaleChangeInterceptor implements HandlerInterceptor { @@ -116,13 +117,14 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons String newLocale = request.getParameter(getParamName()); if (newLocale != null) { if (checkHttpMethod(request.getMethod())) { - LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request); + LocaleContextResolver localeResolver = RequestContextUtils.getLocaleResolver(request); if (localeResolver == null) { throw new IllegalStateException( "No LocaleResolver found: not in a DispatcherServlet request?"); } try { - localeResolver.setLocale(request, response, parseLocaleValue(newLocale)); + localeResolver.setLocaleContext(request, response, + new SimpleLocaleContext(parseLocaleValue(newLocale))); } catch (IllegalArgumentException ex) { if (isIgnoreInvalidLocale()) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/SessionLocaleResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/SessionLocaleResolver.java index 3c4e70465f23..d2a7203a87c8 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/SessionLocaleResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/SessionLocaleResolver.java @@ -30,7 +30,7 @@ import org.springframework.web.util.WebUtils; /** - * {@link org.springframework.web.servlet.LocaleResolver} implementation that + * {@link org.springframework.web.servlet.LocaleContextResolver} implementation that * uses a locale attribute in the user's session in case of a custom setting, * with a fallback to the configured default locale, the request's * {@code Accept-Language} header, or the default locale for the server. diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestContext.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestContext.java index 4167936b12ad..83a441989dcc 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestContext.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestContext.java @@ -32,6 +32,7 @@ import org.springframework.context.MessageSourceResolvable; import org.springframework.context.NoSuchMessageException; import org.springframework.context.i18n.LocaleContext; +import org.springframework.context.i18n.SimpleLocaleContext; import org.springframework.context.i18n.SimpleTimeZoneAwareLocaleContext; import org.springframework.context.i18n.TimeZoneAwareLocaleContext; import org.springframework.lang.Nullable; @@ -44,7 +45,6 @@ import org.springframework.web.bind.EscapedErrors; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.servlet.LocaleContextResolver; -import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.util.HtmlUtils; import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UrlPathHelper; @@ -66,6 +66,7 @@ * * @author Juergen Hoeller * @author Rossen Stoyanchev + * @author Vedran Pavic * @since 03.03.2003 * @see org.springframework.web.servlet.DispatcherServlet * @see org.springframework.web.servlet.view.AbstractView#setRequestContextAttribute @@ -225,18 +226,14 @@ public RequestContext(HttpServletRequest request, @Nullable HttpServletResponse TimeZone timeZone = null; // Determine locale to use for this RequestContext. - LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request); - if (localeResolver instanceof LocaleContextResolver) { - LocaleContext localeContext = ((LocaleContextResolver) localeResolver).resolveLocaleContext(request); + LocaleContextResolver localeResolver = RequestContextUtils.getLocaleResolver(request); + if (localeResolver != null) { + LocaleContext localeContext = localeResolver.resolveLocaleContext(request); locale = localeContext.getLocale(); if (localeContext instanceof TimeZoneAwareLocaleContext) { timeZone = ((TimeZoneAwareLocaleContext) localeContext).getTimeZone(); } } - else if (localeResolver != null) { - // Try LocaleResolver (we're within a DispatcherServlet request). - locale = localeResolver.resolveLocale(request); - } this.locale = locale; this.timeZone = timeZone; @@ -299,7 +296,7 @@ public final Map getModel() { /** * Return the current Locale (falling back to the request locale; never {@code null}). - *

    Typically coming from a DispatcherServlet's {@link LocaleResolver}. + *

    Typically coming from a DispatcherServlet's {@link LocaleContextResolver}. * Also includes a fallback check for JSTL's Locale attribute. * @see RequestContextUtils#getLocale */ @@ -354,34 +351,34 @@ protected TimeZone getFallbackTimeZone() { /** * Change the current locale to the specified one, - * storing the new locale through the configured {@link LocaleResolver}. + * storing the new locale through the configured {@link LocaleContextResolver}. * @param locale the new locale - * @see LocaleResolver#setLocale + * @see LocaleContextResolver#setLocaleContext * @see #changeLocale(java.util.Locale, java.util.TimeZone) */ public void changeLocale(Locale locale) { - LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(this.request); + LocaleContextResolver localeResolver = RequestContextUtils.getLocaleResolver(this.request); if (localeResolver == null) { - throw new IllegalStateException("Cannot change locale if no LocaleResolver configured"); + throw new IllegalStateException("Cannot change locale if no LocaleContextResolver configured"); } - localeResolver.setLocale(this.request, this.response, locale); + localeResolver.setLocaleContext(this.request, this.response, new SimpleLocaleContext(locale)); this.locale = locale; } /** * Change the current locale to the specified locale and time zone context, - * storing the new locale context through the configured {@link LocaleResolver}. + * storing the new locale context through the configured {@link LocaleContextResolver}. * @param locale the new locale * @param timeZone the new time zone * @see LocaleContextResolver#setLocaleContext * @see org.springframework.context.i18n.SimpleTimeZoneAwareLocaleContext */ public void changeLocale(Locale locale, TimeZone timeZone) { - LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(this.request); - if (!(localeResolver instanceof LocaleContextResolver)) { + LocaleContextResolver localeResolver = RequestContextUtils.getLocaleResolver(this.request); + if (localeResolver == null) { throw new IllegalStateException("Cannot change locale context if no LocaleContextResolver configured"); } - ((LocaleContextResolver) localeResolver).setLocaleContext(this.request, this.response, + localeResolver.setLocaleContext(this.request, this.response, new SimpleTimeZoneAwareLocaleContext(locale, timeZone)); this.locale = locale; this.timeZone = timeZone; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestContextUtils.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestContextUtils.java index 7f438a03b09e..3201b19775d4 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestContextUtils.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestContextUtils.java @@ -37,7 +37,6 @@ import org.springframework.web.servlet.FlashMap; import org.springframework.web.servlet.FlashMapManager; import org.springframework.web.servlet.LocaleContextResolver; -import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; @@ -50,6 +49,7 @@ * * @author Juergen Hoeller * @author Rossen Stoyanchev + * @author Vedran Pavic * @since 03.03.2003 * @see RequestContext * @see org.springframework.web.servlet.DispatcherServlet @@ -116,19 +116,19 @@ public static WebApplicationContext findWebApplicationContext(HttpServletRequest } /** - * Return the {@link LocaleResolver} that has been bound to the request by the + * Return the {@link LocaleContextResolver} that has been bound to the request by the * {@link DispatcherServlet}. * @param request current HTTP request * @return the current {@code LocaleResolver}, or {@code null} if not found */ @Nullable - public static LocaleResolver getLocaleResolver(HttpServletRequest request) { - return (LocaleResolver) request.getAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE); + public static LocaleContextResolver getLocaleResolver(HttpServletRequest request) { + return (LocaleContextResolver) request.getAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE); } /** * Retrieve the current locale from the given request, using the - * {@link LocaleResolver} bound to the request by the {@link DispatcherServlet} + * {@link LocaleContextResolver} bound to the request by the {@link DispatcherServlet} * (if available), falling back to the request's locale based on the * {@code Accept-Language} header or the default locale for the server. *

    This method serves as a straightforward alternative to the standard @@ -143,13 +143,19 @@ public static LocaleResolver getLocaleResolver(HttpServletRequest request) { * @see org.springframework.context.i18n.LocaleContextHolder#getLocale() */ public static Locale getLocale(HttpServletRequest request) { - LocaleResolver localeResolver = getLocaleResolver(request); - return (localeResolver != null ? localeResolver.resolveLocale(request) : request.getLocale()); + LocaleContextResolver localeResolver = getLocaleResolver(request); + if (localeResolver != null) { + Locale locale = localeResolver.resolveLocaleContext(request).getLocale(); + if (locale != null) { + return locale; + } + } + return request.getLocale(); } /** * Retrieve the current time zone from the given request, using the - * {@link TimeZoneAwareLocaleContext} in the {@link LocaleResolver} bound to + * {@link TimeZoneAwareLocaleContext} in the {@link LocaleContextResolver} bound to * the request by the {@link DispatcherServlet} (if available). *

    Note: This method returns {@code null} if no specific time zone can be * resolved for the given request. This is in contrast to {@link #getLocale} @@ -167,9 +173,9 @@ public static Locale getLocale(HttpServletRequest request) { */ @Nullable public static TimeZone getTimeZone(HttpServletRequest request) { - LocaleResolver localeResolver = getLocaleResolver(request); - if (localeResolver instanceof LocaleContextResolver localeContextResolver) { - LocaleContext localeContext = localeContextResolver.resolveLocaleContext(request); + LocaleContextResolver localeResolver = getLocaleResolver(request); + if (localeResolver != null) { + LocaleContext localeContext = localeResolver.resolveLocaleContext(request); if (localeContext instanceof TimeZoneAwareLocaleContext timeZoneAwareLocaleContext) { return timeZoneAwareLocaleContext.getTimeZone(); } diff --git a/spring-webmvc/src/main/resources/org/springframework/web/servlet/DispatcherServlet.properties b/spring-webmvc/src/main/resources/org/springframework/web/servlet/DispatcherServlet.properties index c55b61864e96..bdadfd1c1707 100644 --- a/spring-webmvc/src/main/resources/org/springframework/web/servlet/DispatcherServlet.properties +++ b/spring-webmvc/src/main/resources/org/springframework/web/servlet/DispatcherServlet.properties @@ -2,7 +2,7 @@ # Used as fallback when no matching beans are found in the DispatcherServlet context. # Not meant to be customized by application developers. -org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver +org.springframework.web.servlet.LocaleContextResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver @@ -24,4 +24,4 @@ org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework. org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver -org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager \ No newline at end of file +org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java index c52eea704079..d4f8591870ca 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java @@ -87,7 +87,7 @@ import org.springframework.web.servlet.FlashMapManager; import org.springframework.web.servlet.HandlerExecutionChain; import org.springframework.web.servlet.HandlerInterceptor; -import org.springframework.web.servlet.LocaleResolver; +import org.springframework.web.servlet.LocaleContextResolver; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.RequestToViewNameTranslator; import org.springframework.web.servlet.ThemeResolver; @@ -232,7 +232,7 @@ public void testDefaultConfig() throws Exception { assertThat(appContext.getBean(ConversionService.class)).isNotNull(); assertThat(appContext.getBean(LocalValidatorFactoryBean.class)).isNotNull(); assertThat(appContext.getBean(Validator.class)).isNotNull(); - assertThat(appContext.getBean("localeResolver", LocaleResolver.class)).isNotNull(); + assertThat(appContext.getBean("localeResolver", LocaleContextResolver.class)).isNotNull(); assertThat(appContext.getBean("themeResolver", ThemeResolver.class)).isNotNull(); assertThat(appContext.getBean("viewNameTranslator", RequestToViewNameTranslator.class)).isNotNull(); assertThat(appContext.getBean("flashMapManager", FlashMapManager.class)).isNotNull(); diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportTests.java index c5c288a1ae8e..5dc7632f78ac 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -67,7 +67,7 @@ import org.springframework.web.servlet.HandlerExecutionChain; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.HandlerMapping; -import org.springframework.web.servlet.LocaleResolver; +import org.springframework.web.servlet.LocaleContextResolver; import org.springframework.web.servlet.RequestToViewNameTranslator; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping; @@ -326,7 +326,7 @@ public void defaultPathMatchConfiguration() { @Test public void defaultLocaleResolverConfiguration() { ApplicationContext context = initContext(WebConfig.class); - LocaleResolver localeResolver = context.getBean(LOCALE_RESOLVER_BEAN_NAME, LocaleResolver.class); + LocaleContextResolver localeResolver = context.getBean(LOCALE_RESOLVER_BEAN_NAME, LocaleContextResolver.class); assertThat(localeResolver).isNotNull(); assertThat(localeResolver).isInstanceOf(AcceptHeaderLocaleResolver.class); diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/AcceptHeaderLocaleResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/AcceptHeaderLocaleResolverTests.java index 6b5243d9a251..01594f733bd3 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/AcceptHeaderLocaleResolverTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/AcceptHeaderLocaleResolverTests.java @@ -49,38 +49,38 @@ class AcceptHeaderLocaleResolverTests { @Test void resolve() { - assertThat(this.resolver.resolveLocale(request(CANADA))).isEqualTo(CANADA); - assertThat(this.resolver.resolveLocale(request(US, CANADA))).isEqualTo(US); + assertThat(this.resolver.resolveLocaleContext(request(CANADA)).getLocale()).isEqualTo(CANADA); + assertThat(this.resolver.resolveLocaleContext(request(US, CANADA)).getLocale()).isEqualTo(US); } @Test void resolvePreferredSupported() { this.resolver.setSupportedLocales(Collections.singletonList(CANADA)); - assertThat(this.resolver.resolveLocale(request(US, CANADA))).isEqualTo(CANADA); + assertThat(this.resolver.resolveLocaleContext(request(US, CANADA)).getLocale()).isEqualTo(CANADA); } @Test void resolvePreferredNotSupported() { this.resolver.setSupportedLocales(Collections.singletonList(CANADA)); - assertThat(this.resolver.resolveLocale(request(US, UK))).isEqualTo(US); + assertThat(this.resolver.resolveLocaleContext(request(US, UK)).getLocale()).isEqualTo(US); } @Test void resolvePreferredAgainstLanguageOnly() { this.resolver.setSupportedLocales(Collections.singletonList(ENGLISH)); - assertThat(this.resolver.resolveLocale(request(GERMANY, US, UK))).isEqualTo(ENGLISH); + assertThat(this.resolver.resolveLocaleContext(request(GERMANY, US, UK)).getLocale()).isEqualTo(ENGLISH); } @Test void resolvePreferredAgainstCountryIfPossible() { this.resolver.setSupportedLocales(Arrays.asList(ENGLISH, UK)); - assertThat(this.resolver.resolveLocale(request(GERMANY, US, UK))).isEqualTo(UK); + assertThat(this.resolver.resolveLocaleContext(request(GERMANY, US, UK)).getLocale()).isEqualTo(UK); } @Test void resolvePreferredAgainstLanguageWithMultipleSupportedLocales() { this.resolver.setSupportedLocales(Arrays.asList(GERMAN, US)); - assertThat(this.resolver.resolveLocale(request(GERMANY, US, UK))).isEqualTo(GERMAN); + assertThat(this.resolver.resolveLocaleContext(request(GERMANY, US, UK)).getLocale()).isEqualTo(GERMAN); } @Test @@ -91,18 +91,18 @@ void resolvePreferredNotSupportedWithDefault() { MockHttpServletRequest request = new MockHttpServletRequest(); request.addHeader("Accept-Language", KOREA.toLanguageTag()); request.setPreferredLocales(Collections.singletonList(KOREA)); - assertThat(this.resolver.resolveLocale(request)).isEqualTo(Locale.JAPAN); + assertThat(this.resolver.resolveLocaleContext(request).getLocale()).isEqualTo(Locale.JAPAN); } @Test void defaultLocale() { this.resolver.setDefaultLocale(JAPANESE); MockHttpServletRequest request = new MockHttpServletRequest(); - assertThat(this.resolver.resolveLocale(request)).isEqualTo(JAPANESE); + assertThat(this.resolver.resolveLocaleContext(request).getLocale()).isEqualTo(JAPANESE); request.addHeader("Accept-Language", US.toLanguageTag()); request.setPreferredLocales(Collections.singletonList(US)); - assertThat(this.resolver.resolveLocale(request)).isEqualTo(US); + assertThat(this.resolver.resolveLocaleContext(request).getLocale()).isEqualTo(US); } diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/CookieLocaleResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/CookieLocaleResolverTests.java index 4b9152b8961f..7fa886b6be31 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/CookieLocaleResolverTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/CookieLocaleResolverTests.java @@ -61,7 +61,7 @@ void resolveLocale() { request.setCookies(cookie); resolver = new CookieLocaleResolver("LanguageKoekje"); - Locale loc = resolver.resolveLocale(request); + Locale loc = resolver.resolveLocaleContext(request).getLocale(); assertThat(loc.getLanguage()).isEqualTo("nl"); } @@ -141,8 +141,8 @@ void resolveLocaleContextWithInvalidTimeZoneOnErrorDispatch() { } @Test - void setAndResolveLocale() { - resolver.setLocale(request, response, new Locale("nl", "")); + void setAndResolveLocaleContext() { + resolver.setLocaleContext(request, response, new SimpleLocaleContext(new Locale("nl", ""))); MockCookie cookie = MockCookie.parse(response.getHeader(HttpHeaders.SET_COOKIE)); assertThat(cookie).isNotNull(); @@ -155,19 +155,6 @@ void setAndResolveLocale() { request = new MockHttpServletRequest(); request.setCookies(cookie); - resolver = new CookieLocaleResolver(); - Locale loc = resolver.resolveLocale(request); - assertThat(loc.getLanguage()).isEqualTo("nl"); - } - - @Test - void setAndResolveLocaleContext() { - resolver.setLocaleContext(request, response, new SimpleLocaleContext(new Locale("nl", ""))); - - Cookie cookie = response.getCookie(CookieLocaleResolver.DEFAULT_COOKIE_NAME); - request = new MockHttpServletRequest(); - request.setCookies(cookie); - resolver = new CookieLocaleResolver(); LocaleContext loc = resolver.resolveLocaleContext(request); assertThat(loc.getLocale().getLanguage()).isEqualTo("nl"); @@ -210,7 +197,7 @@ void setAndResolveLocaleContextWithTimeZoneOnly() { @Test void setAndResolveLocaleWithCountry() { - resolver.setLocale(request, response, new Locale("de", "AT")); + resolver.setLocaleContext(request, response, new SimpleLocaleContext(new Locale("de", "AT"))); MockCookie cookie = MockCookie.parse(response.getHeader(HttpHeaders.SET_COOKIE)); assertThat(cookie).isNotNull(); @@ -225,7 +212,7 @@ void setAndResolveLocaleWithCountry() { request.setCookies(cookie); resolver = new CookieLocaleResolver(); - Locale loc = resolver.resolveLocale(request); + Locale loc = resolver.resolveLocaleContext(request).getLocale(); assertThat(loc.getLanguage()).isEqualTo("de"); assertThat(loc.getCountry()).isEqualTo("AT"); } @@ -233,7 +220,7 @@ void setAndResolveLocaleWithCountry() { @Test void setAndResolveLocaleWithCountryAsLegacyJava() { resolver.setLanguageTagCompliant(false); - resolver.setLocale(request, response, new Locale("de", "AT")); + resolver.setLocaleContext(request, response, new SimpleLocaleContext(new Locale("de", "AT"))); MockCookie cookie = MockCookie.parse(response.getHeader(HttpHeaders.SET_COOKIE)); assertThat(cookie).isNotNull(); @@ -248,7 +235,7 @@ void setAndResolveLocaleWithCountryAsLegacyJava() { request.setCookies(cookie); resolver = new CookieLocaleResolver(); - Locale loc = resolver.resolveLocale(request); + Locale loc = resolver.resolveLocaleContext(request).getLocale(); assertThat(loc.getLanguage()).isEqualTo("de"); assertThat(loc.getCountry()).isEqualTo("AT"); } @@ -261,7 +248,7 @@ void customCookie() { resolver.setCookieMaxAge(Duration.ofSeconds(10000)); resolver.setCookieSecure(true); resolver.setCookieSameSite("Lax"); - resolver.setLocale(request, response, new Locale("nl", "")); + resolver.setLocaleContext(request, response, new SimpleLocaleContext(new Locale("nl", ""))); MockCookie cookie = MockCookie.parse(response.getHeader(HttpHeaders.SET_COOKIE)); assertThat(cookie).isNotNull(); @@ -276,18 +263,10 @@ void customCookie() { request.setCookies(cookie); resolver = new CookieLocaleResolver("LanguageKoek"); - Locale loc = resolver.resolveLocale(request); + Locale loc = resolver.resolveLocaleContext(request).getLocale(); assertThat(loc.getLanguage()).isEqualTo("nl"); } - @Test - void resolveLocaleWithoutCookie() { - request.addPreferredLocale(Locale.TAIWAN); - - Locale loc = resolver.resolveLocale(request); - assertThat(loc).isEqualTo(request.getLocale()); - } - @Test void resolveLocaleContextWithoutCookie() { request.addPreferredLocale(Locale.TAIWAN); @@ -298,16 +277,6 @@ void resolveLocaleContextWithoutCookie() { assertThat(((TimeZoneAwareLocaleContext) loc).getTimeZone()).isNull(); } - @Test - void resolveLocaleWithoutCookieAndDefaultLocale() { - request.addPreferredLocale(Locale.TAIWAN); - - resolver.setDefaultLocale(Locale.GERMAN); - - Locale loc = resolver.resolveLocale(request); - assertThat(loc).isEqualTo(Locale.GERMAN); - } - @Test void resolveLocaleContextWithoutCookieAndDefaultLocale() { request.addPreferredLocale(Locale.TAIWAN); @@ -321,16 +290,6 @@ void resolveLocaleContextWithoutCookieAndDefaultLocale() { assertThat(((TimeZoneAwareLocaleContext) loc).getTimeZone()).isEqualTo(TimeZone.getTimeZone("GMT+1")); } - @Test - void resolveLocaleWithCookieWithoutLocale() { - request.addPreferredLocale(Locale.TAIWAN); - Cookie cookie = new Cookie(CookieLocaleResolver.DEFAULT_COOKIE_NAME, ""); - request.setCookies(cookie); - - Locale loc = resolver.resolveLocale(request); - assertThat(loc).isEqualTo(request.getLocale()); - } - @Test void resolveLocaleContextWithCookieWithoutLocale() { request.addPreferredLocale(Locale.TAIWAN); @@ -343,23 +302,6 @@ void resolveLocaleContextWithCookieWithoutLocale() { assertThat(((TimeZoneAwareLocaleContext) loc).getTimeZone()).isNull(); } - @Test - void setLocaleToNull() { - request.addPreferredLocale(Locale.TAIWAN); - Cookie cookie = new Cookie(CookieLocaleResolver.DEFAULT_COOKIE_NAME, Locale.UK.toString()); - request.setCookies(cookie); - - resolver.setLocale(request, response, null); - Locale locale = (Locale) request.getAttribute(CookieLocaleResolver.LOCALE_REQUEST_ATTRIBUTE_NAME); - assertThat(locale).isEqualTo(Locale.TAIWAN); - - Cookie[] cookies = response.getCookies(); - assertThat(cookies).hasSize(1); - Cookie localeCookie = cookies[0]; - assertThat(localeCookie.getName()).isEqualTo(CookieLocaleResolver.DEFAULT_COOKIE_NAME); - assertThat(localeCookie.getValue()).isEqualTo(""); - } - @Test void setLocaleContextToNull() { request.addPreferredLocale(Locale.TAIWAN); @@ -379,24 +321,6 @@ void setLocaleContextToNull() { assertThat(localeCookie.getValue()).isEqualTo(""); } - @Test - void setLocaleToNullWithDefault() { - request.addPreferredLocale(Locale.TAIWAN); - Cookie cookie = new Cookie(CookieLocaleResolver.DEFAULT_COOKIE_NAME, Locale.UK.toString()); - request.setCookies(cookie); - - resolver.setDefaultLocale(Locale.CANADA_FRENCH); - resolver.setLocale(request, response, null); - Locale locale = (Locale) request.getAttribute(CookieLocaleResolver.LOCALE_REQUEST_ATTRIBUTE_NAME); - assertThat(locale).isEqualTo(Locale.CANADA_FRENCH); - - Cookie[] cookies = response.getCookies(); - assertThat(cookies).hasSize(1); - Cookie localeCookie = cookies[0]; - assertThat(localeCookie.getName()).isEqualTo(CookieLocaleResolver.DEFAULT_COOKIE_NAME); - assertThat(localeCookie.getValue()).isEqualTo(""); - } - @Test void setLocaleContextToNullWithDefault() { request.addPreferredLocale(Locale.TAIWAN); @@ -424,7 +348,7 @@ void customDefaultLocaleFunction() { resolver.setDefaultLocaleFunction(request -> Locale.GERMAN); - assertThat(resolver.resolveLocale(request)).isEqualTo(Locale.GERMAN); + assertThat(resolver.resolveLocaleContext(request).getLocale()).isEqualTo(Locale.GERMAN); } @Test diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/LocaleResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/LocaleResolverTests.java index 85d583c25c52..16c38f74e56b 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/LocaleResolverTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/LocaleResolverTests.java @@ -26,7 +26,6 @@ import org.springframework.context.i18n.SimpleTimeZoneAwareLocaleContext; import org.springframework.context.i18n.TimeZoneAwareLocaleContext; import org.springframework.web.servlet.LocaleContextResolver; -import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.testfixture.servlet.MockHttpServletRequest; import org.springframework.web.testfixture.servlet.MockHttpServletResponse; import org.springframework.web.testfixture.servlet.MockServletContext; @@ -35,7 +34,7 @@ import static org.assertj.core.api.Assertions.fail; /** - * Unit tests for various {@link LocaleResolver} implementations. + * Unit tests for various {@link LocaleContextResolver} implementations. * * @author Juergen Hoeller * @author Vedran Pavic @@ -63,7 +62,7 @@ void sessionLocaleResolver() { doTest(new SessionLocaleResolver(), true, true); } - private void doTest(LocaleResolver localeResolver, boolean shouldSet, boolean timeZoneAware) { + private void doTest(LocaleContextResolver localeResolver, boolean shouldSet, boolean timeZoneAware) { // create mocks MockServletContext context = new MockServletContext(); MockHttpServletRequest request = new MockHttpServletRequest(context); @@ -71,14 +70,14 @@ private void doTest(LocaleResolver localeResolver, boolean shouldSet, boolean ti MockHttpServletResponse response = new MockHttpServletResponse(); // check original locale - Locale locale = localeResolver.resolveLocale(request); + Locale locale = localeResolver.resolveLocaleContext(request).getLocale(); assertThat(locale).isEqualTo(Locale.UK); // set new locale try { - localeResolver.setLocale(request, response, Locale.GERMANY); + localeResolver.setLocaleContext(request, response, new SimpleLocaleContext(Locale.GERMANY)); assertThat(shouldSet).as("should not be able to set Locale").isTrue(); // check new locale - locale = localeResolver.resolveLocale(request); + locale = localeResolver.resolveLocaleContext(request).getLocale(); assertThat(locale).isEqualTo(Locale.GERMANY); } catch (UnsupportedOperationException ex) { @@ -86,70 +85,68 @@ private void doTest(LocaleResolver localeResolver, boolean shouldSet, boolean ti } // check LocaleContext - if (localeResolver instanceof LocaleContextResolver localeContextResolver) { - LocaleContext localeContext = localeContextResolver.resolveLocaleContext(request); - if (shouldSet) { - assertThat(localeContext.getLocale()).isEqualTo(Locale.GERMANY); + LocaleContext localeContext = localeResolver.resolveLocaleContext(request); + if (shouldSet) { + assertThat(localeContext.getLocale()).isEqualTo(Locale.GERMANY); + } + else { + assertThat(localeContext.getLocale()).isEqualTo(Locale.UK); + } + if (timeZoneAware) { + boolean condition2 = localeContext instanceof TimeZoneAwareLocaleContext; + assertThat(condition2).isTrue(); + assertThat(((TimeZoneAwareLocaleContext) localeContext).getTimeZone()).isNull(); + } + + if (localeResolver instanceof AbstractLocaleContextResolver) { + ((AbstractLocaleContextResolver) localeResolver).setDefaultTimeZone(TimeZone.getTimeZone("GMT+1")); + request.removeAttribute(CookieLocaleResolver.LOCALE_REQUEST_ATTRIBUTE_NAME); + localeResolver.resolveLocaleContext(request); + if (timeZoneAware) { + assertThat(TimeZone.getTimeZone("GMT+1")).isEqualTo(((TimeZoneAwareLocaleContext) localeContext).getTimeZone()); } - else { - assertThat(localeContext.getLocale()).isEqualTo(Locale.UK); + } + + try { + localeResolver.setLocaleContext(request, response, new SimpleLocaleContext(Locale.US)); + if (!shouldSet) { + fail("should not be able to set Locale"); } - if (timeZoneAware) { - boolean condition2 = localeContext instanceof TimeZoneAwareLocaleContext; - assertThat(condition2).isTrue(); + localeContext = localeResolver.resolveLocaleContext(request); + assertThat(localeContext.getLocale()).isEqualTo(Locale.US); + if (localeResolver instanceof AbstractLocaleContextResolver) { + assertThat(TimeZone.getTimeZone("GMT+1")).isEqualTo(((TimeZoneAwareLocaleContext) localeContext).getTimeZone()); + } + else { assertThat(((TimeZoneAwareLocaleContext) localeContext).getTimeZone()).isNull(); } - if (localeContextResolver instanceof AbstractLocaleContextResolver) { - ((AbstractLocaleContextResolver) localeContextResolver).setDefaultTimeZone(TimeZone.getTimeZone("GMT+1")); + localeResolver.setLocaleContext(request, response, + new SimpleTimeZoneAwareLocaleContext(Locale.GERMANY, TimeZone.getTimeZone("GMT+2"))); + localeContext = localeResolver.resolveLocaleContext(request); + assertThat(localeContext.getLocale()).isEqualTo(Locale.GERMANY); + boolean condition1 = localeContext instanceof TimeZoneAwareLocaleContext; + assertThat(condition1).isTrue(); + assertThat(TimeZone.getTimeZone("GMT+2")).isEqualTo(((TimeZoneAwareLocaleContext) localeContext).getTimeZone()); + + localeResolver.setLocaleContext(request, response, + new SimpleTimeZoneAwareLocaleContext(null, TimeZone.getTimeZone("GMT+3"))); + localeContext = localeResolver.resolveLocaleContext(request); + assertThat(localeContext.getLocale()).isEqualTo(Locale.UK); + boolean condition = localeContext instanceof TimeZoneAwareLocaleContext; + assertThat(condition).isTrue(); + assertThat(TimeZone.getTimeZone("GMT+3")).isEqualTo(((TimeZoneAwareLocaleContext) localeContext).getTimeZone()); + + if (localeResolver instanceof AbstractLocaleContextResolver) { + ((AbstractLocaleContextResolver) localeResolver).setDefaultLocale(Locale.GERMANY); request.removeAttribute(CookieLocaleResolver.LOCALE_REQUEST_ATTRIBUTE_NAME); - localeContextResolver.resolveLocaleContext(request); - if (timeZoneAware) { - assertThat(TimeZone.getTimeZone("GMT+1")).isEqualTo(((TimeZoneAwareLocaleContext) localeContext).getTimeZone()); - } - } - - try { - localeContextResolver.setLocaleContext(request, response, new SimpleLocaleContext(Locale.US)); - if (!shouldSet) { - fail("should not be able to set Locale"); - } - localeContext = localeContextResolver.resolveLocaleContext(request); - assertThat(localeContext.getLocale()).isEqualTo(Locale.US); - if (localeContextResolver instanceof AbstractLocaleContextResolver) { - assertThat(TimeZone.getTimeZone("GMT+1")).isEqualTo(((TimeZoneAwareLocaleContext) localeContext).getTimeZone()); - } - else { - assertThat(((TimeZoneAwareLocaleContext) localeContext).getTimeZone()).isNull(); - } - - localeContextResolver.setLocaleContext(request, response, - new SimpleTimeZoneAwareLocaleContext(Locale.GERMANY, TimeZone.getTimeZone("GMT+2"))); - localeContext = localeContextResolver.resolveLocaleContext(request); + localeResolver.resolveLocaleContext(request); assertThat(localeContext.getLocale()).isEqualTo(Locale.GERMANY); - boolean condition1 = localeContext instanceof TimeZoneAwareLocaleContext; - assertThat(condition1).isTrue(); - assertThat(TimeZone.getTimeZone("GMT+2")).isEqualTo(((TimeZoneAwareLocaleContext) localeContext).getTimeZone()); - - localeContextResolver.setLocaleContext(request, response, - new SimpleTimeZoneAwareLocaleContext(null, TimeZone.getTimeZone("GMT+3"))); - localeContext = localeContextResolver.resolveLocaleContext(request); - assertThat(localeContext.getLocale()).isEqualTo(Locale.UK); - boolean condition = localeContext instanceof TimeZoneAwareLocaleContext; - assertThat(condition).isTrue(); - assertThat(TimeZone.getTimeZone("GMT+3")).isEqualTo(((TimeZoneAwareLocaleContext) localeContext).getTimeZone()); - - if (localeContextResolver instanceof AbstractLocaleContextResolver) { - ((AbstractLocaleContextResolver) localeContextResolver).setDefaultLocale(Locale.GERMANY); - request.removeAttribute(CookieLocaleResolver.LOCALE_REQUEST_ATTRIBUTE_NAME); - localeContextResolver.resolveLocaleContext(request); - assertThat(localeContext.getLocale()).isEqualTo(Locale.GERMANY); - } } - catch (UnsupportedOperationException ex) { - if (shouldSet) { - fail("should be able to set Locale"); - } + } + catch (UnsupportedOperationException ex) { + if (shouldSet) { + fail("should be able to set Locale"); } } } diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/SessionLocaleResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/SessionLocaleResolverTests.java index de9256f4bdef..2f61daa231f5 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/SessionLocaleResolverTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/SessionLocaleResolverTests.java @@ -22,6 +22,7 @@ import jakarta.servlet.http.HttpSession; import org.junit.jupiter.api.Test; +import org.springframework.context.i18n.SimpleLocaleContext; import org.springframework.context.i18n.TimeZoneAwareLocaleContext; import org.springframework.web.testfixture.servlet.MockHttpServletRequest; import org.springframework.web.testfixture.servlet.MockHttpServletResponse; @@ -48,27 +49,27 @@ class SessionLocaleResolverTests { void resolveLocale() { request.getSession().setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, Locale.GERMAN); - assertThat(resolver.resolveLocale(request)).isEqualTo(Locale.GERMAN); + assertThat(resolver.resolveLocaleContext(request).getLocale()).isEqualTo(Locale.GERMAN); } @Test void setAndResolveLocale() { - resolver.setLocale(request, response, Locale.GERMAN); - assertThat(resolver.resolveLocale(request)).isEqualTo(Locale.GERMAN); + resolver.setLocaleContext(request, response, new SimpleLocaleContext(Locale.GERMAN)); + assertThat(resolver.resolveLocaleContext(request).getLocale()).isEqualTo(Locale.GERMAN); HttpSession session = request.getSession(); request = new MockHttpServletRequest(); request.setSession(session); resolver = new SessionLocaleResolver(); - assertThat(resolver.resolveLocale(request)).isEqualTo(Locale.GERMAN); + assertThat(resolver.resolveLocaleContext(request).getLocale()).isEqualTo(Locale.GERMAN); } @Test void resolveLocaleWithoutSession() throws Exception { request.addPreferredLocale(Locale.TAIWAN); - assertThat(resolver.resolveLocale(request)).isEqualTo(request.getLocale()); + assertThat(resolver.resolveLocaleContext(request).getLocale()).isEqualTo(request.getLocale()); } @Test @@ -77,7 +78,7 @@ void resolveLocaleWithoutSessionAndDefaultLocale() throws Exception { resolver.setDefaultLocale(Locale.GERMAN); - assertThat(resolver.resolveLocale(request)).isEqualTo(Locale.GERMAN); + assertThat(resolver.resolveLocaleContext(request).getLocale()).isEqualTo(Locale.GERMAN); } @Test @@ -85,7 +86,7 @@ void setLocaleToNullLocale() throws Exception { request.addPreferredLocale(Locale.TAIWAN); request.getSession().setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, Locale.GERMAN); - resolver.setLocale(request, response, null); + resolver.setLocaleContext(request, response, null); Locale locale = (Locale) request.getSession().getAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME); assertThat(locale).isNull(); @@ -94,7 +95,7 @@ void setLocaleToNullLocale() throws Exception { request.addPreferredLocale(Locale.TAIWAN); request.setSession(session); resolver = new SessionLocaleResolver(); - assertThat(resolver.resolveLocale(request)).isEqualTo(Locale.TAIWAN); + assertThat(resolver.resolveLocaleContext(request).getLocale()).isEqualTo(Locale.TAIWAN); } @Test @@ -103,7 +104,7 @@ void customDefaultLocaleFunction() { resolver.setDefaultLocaleFunction(request -> Locale.GERMAN); - assertThat(resolver.resolveLocale(request)).isEqualTo(Locale.GERMAN); + assertThat(resolver.resolveLocaleContext(request).getLocale()).isEqualTo(Locale.GERMAN); } @Test diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/AbstractTagTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/AbstractTagTests.java index 28c9a03708a2..8c28c1be1500 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/AbstractTagTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/AbstractTagTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ import org.springframework.web.context.WebApplicationContext; import org.springframework.web.servlet.DispatcherServlet; -import org.springframework.web.servlet.LocaleResolver; +import org.springframework.web.servlet.LocaleContextResolver; import org.springframework.web.servlet.SimpleWebApplicationContext; import org.springframework.web.servlet.ThemeResolver; import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver; @@ -49,7 +49,7 @@ protected MockPageContext createPageContext() { MockHttpServletResponse response = new MockHttpServletResponse(); if (inDispatcherServlet()) { request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac); - LocaleResolver lr = new AcceptHeaderLocaleResolver(); + LocaleContextResolver lr = new AcceptHeaderLocaleResolver(); request.setAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE, lr); ThemeResolver tr = new FixedThemeResolver(); request.setAttribute(DispatcherServlet.THEME_RESOLVER_ATTRIBUTE, tr); diff --git a/src/docs/asciidoc/web/webmvc.adoc b/src/docs/asciidoc/web/webmvc.adoc index 841b3fc8aa6f..537938ae33e1 100644 --- a/src/docs/asciidoc/web/webmvc.adoc +++ b/src/docs/asciidoc/web/webmvc.adoc @@ -904,7 +904,7 @@ See <> under <> for configuration details Most parts of Spring's architecture support internationalization, as the Spring web MVC framework does. `DispatcherServlet` lets you automatically resolve messages -by using the client's locale. This is done with `LocaleResolver` objects. +by using the client's locale. This is done with `LocaleContextResolver` objects. When a request comes in, the `DispatcherServlet` looks for a locale resolver and, if it finds one, it tries to use it to set the locale. By using the `RequestContext.getLocale()` @@ -1013,7 +1013,7 @@ modifies the corresponding `HttpSession` attributes against the current `HttpSer You can enable changing of locales by adding the `LocaleChangeInterceptor` to one of the `HandlerMapping` definitions. It detects a parameter in the request and changes the locale -accordingly, calling the `setLocale` method on the `LocaleResolver` in the dispatcher's +accordingly, calling the `setLocale` method on the `LocaleContextResolver` in the dispatcher's application context. The next example shows that calls to all `{asterisk}.view` resources that contain a parameter named `siteLanguage` now changes the locale. So, for example, a request for the URL, `https://www.sf.net/home.view?siteLanguage=nl`, changes the site @@ -1111,7 +1111,7 @@ background image with Dutch text on it. After you define themes, as described in the <>, you decide which theme to use. The `DispatcherServlet` looks for a bean named `themeResolver` to find out which `ThemeResolver` implementation to use. A theme resolver works in much the same -way as a `LocaleResolver`. It detects the theme to use for a particular request and can also +way as a `LocaleContextResolver`. It detects the theme to use for a particular request and can also alter the request's theme. The following table describes the theme resolvers provided by Spring: [[mvc-theme-resolver-impls-tbl]] @@ -2098,8 +2098,8 @@ and others) and is equivalent to `required=false`. | The HTTP method of the request. | `java.util.Locale` -| The current request locale, determined by the most specific `LocaleResolver` available (in - effect, the configured `LocaleResolver` or `LocaleContextResolver`). +| The current request locale, determined by the most specific `LocaleContextResolver` available (in + effect, the configured `LocaleContextResolver`). | `java.util.TimeZone` + `java.time.ZoneId` | The time zone associated with the current request, as determined by a `LocaleContextResolver`. @@ -3932,8 +3932,8 @@ level, <> mechanism. | The HTTP method of the request. | `java.util.Locale` -| The current request locale, determined by the most specific `LocaleResolver` available -- in - effect, the configured `LocaleResolver` or `LocaleContextResolver`. +| The current request locale, determined by the most specific `LocaleContextResolver` available -- in + effect, the configured `LocaleContextResolver`. | `java.util.TimeZone`, `java.time.ZoneId` | The time zone associated with the current request, as determined by a `LocaleContextResolver`.