diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ServerWebExchangeArgumentResolver.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ServerWebExchangeArgumentResolver.java
index 24b3d90d02..c9e8433bcb 100644
--- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ServerWebExchangeArgumentResolver.java
+++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ServerWebExchangeArgumentResolver.java
@@ -16,12 +16,19 @@
package org.springframework.web.reactive.result.method.annotation;
+import java.time.ZoneId;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import org.springframework.context.i18n.LocaleContext;
+import org.springframework.context.i18n.TimeZoneAwareLocaleContext;
import org.springframework.core.MethodParameter;
import org.springframework.core.ReactiveAdapterRegistry;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
+import org.springframework.lang.Nullable;
import org.springframework.web.reactive.BindingContext;
import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolverSupport;
import org.springframework.web.reactive.result.method.SyncHandlerMethodArgumentResolver;
@@ -36,6 +43,9 @@ import org.springframework.web.util.UriComponentsBuilder;
*
{@link ServerHttpRequest}
* {@link ServerHttpResponse}
* {@link HttpMethod}
+ * {@link Locale}
+ * {@link TimeZone}
+ * {@link ZoneId}
* {@link UriBuilder} or {@link UriComponentsBuilder} -- for building URL's
* relative to the current request
*
@@ -63,6 +73,9 @@ public class ServerWebExchangeArgumentResolver extends HandlerMethodArgumentReso
ServerHttpRequest.class.isAssignableFrom(type) ||
ServerHttpResponse.class.isAssignableFrom(type) ||
HttpMethod.class == type ||
+ Locale.class == type ||
+ TimeZone.class == type ||
+ ZoneId.class == type ||
UriBuilder.class == type || UriComponentsBuilder.class == type);
}
@@ -83,6 +96,19 @@ public class ServerWebExchangeArgumentResolver extends HandlerMethodArgumentReso
else if (HttpMethod.class == paramType) {
return exchange.getRequest().getMethod();
}
+ else if (Locale.class == paramType) {
+ return exchange.getLocaleContext().getLocale();
+ }
+ else if (TimeZone.class == paramType) {
+ LocaleContext localeContext = exchange.getLocaleContext();
+ TimeZone timeZone = getTimeZone(localeContext);
+ return timeZone != null ? timeZone : TimeZone.getDefault();
+ }
+ else if (ZoneId.class == paramType) {
+ LocaleContext localeContext = exchange.getLocaleContext();
+ TimeZone timeZone = getTimeZone(localeContext);
+ return timeZone != null ? timeZone.toZoneId() : ZoneId.systemDefault();
+ }
else if (UriBuilder.class == paramType || UriComponentsBuilder.class == paramType) {
return UriComponentsBuilder.fromHttpRequest(exchange.getRequest());
}
@@ -93,4 +119,13 @@ public class ServerWebExchangeArgumentResolver extends HandlerMethodArgumentReso
}
}
+ @Nullable
+ private TimeZone getTimeZone(LocaleContext localeContext) {
+ TimeZone timeZone = null;
+ if (localeContext instanceof TimeZoneAwareLocaleContext) {
+ timeZone = ((TimeZoneAwareLocaleContext) localeContext).getTimeZone();
+ }
+ return timeZone;
+ }
+
}
diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ServerWebExchangeArgumentResolverTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ServerWebExchangeArgumentResolverTests.java
index 4edfa5b265..5ba3f13136 100644
--- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ServerWebExchangeArgumentResolverTests.java
+++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ServerWebExchangeArgumentResolverTests.java
@@ -16,6 +16,10 @@
package org.springframework.web.reactive.result.method.annotation;
+import java.time.ZoneId;
+import java.util.Locale;
+import java.util.TimeZone;
+
import org.junit.Test;
import reactor.core.publisher.Mono;
@@ -60,6 +64,9 @@ public class ServerWebExchangeArgumentResolverTests {
assertTrue(this.resolver.supportsParameter(this.testMethod.arg(ServerHttpRequest.class)));
assertTrue(this.resolver.supportsParameter(this.testMethod.arg(ServerHttpResponse.class)));
assertTrue(this.resolver.supportsParameter(this.testMethod.arg(HttpMethod.class)));
+ assertTrue(this.resolver.supportsParameter(this.testMethod.arg(Locale.class)));
+ assertTrue(this.resolver.supportsParameter(this.testMethod.arg(TimeZone.class)));
+ assertTrue(this.resolver.supportsParameter(this.testMethod.arg(ZoneId.class)));
assertTrue(this.resolver.supportsParameter(this.testMethod.arg(UriComponentsBuilder.class)));
assertTrue(this.resolver.supportsParameter(this.testMethod.arg(UriBuilder.class)));
@@ -81,6 +88,13 @@ public class ServerWebExchangeArgumentResolverTests {
testResolveArgument(this.testMethod.arg(ServerHttpRequest.class), this.exchange.getRequest());
testResolveArgument(this.testMethod.arg(ServerHttpResponse.class), this.exchange.getResponse());
testResolveArgument(this.testMethod.arg(HttpMethod.class), HttpMethod.GET);
+ testResolveArgument(this.testMethod.arg(TimeZone.class), TimeZone.getDefault());
+ testResolveArgument(this.testMethod.arg(ZoneId.class), ZoneId.systemDefault());
+ }
+
+ private void testResolveArgument(MethodParameter parameter, Object expected) {
+ Mono