Skip to content

Commit 869b818

Browse files
committed
WebFlux support for LocaleContext related arguments
Issue: SPR-15998
1 parent 0f1bd49 commit 869b818

File tree

3 files changed

+59
-13
lines changed

3 files changed

+59
-13
lines changed

spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ServerWebExchangeArgumentResolver.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,19 @@
1616

1717
package org.springframework.web.reactive.result.method.annotation;
1818

19+
import java.time.ZoneId;
20+
import java.util.Locale;
21+
import java.util.TimeZone;
22+
23+
import org.springframework.context.i18n.LocaleContext;
24+
import org.springframework.context.i18n.TimeZoneAwareLocaleContext;
1925
import org.springframework.core.MethodParameter;
2026
import org.springframework.core.ReactiveAdapterRegistry;
2127
import org.springframework.http.HttpMethod;
2228
import org.springframework.http.HttpRequest;
2329
import org.springframework.http.server.reactive.ServerHttpRequest;
2430
import org.springframework.http.server.reactive.ServerHttpResponse;
31+
import org.springframework.lang.Nullable;
2532
import org.springframework.web.reactive.BindingContext;
2633
import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolverSupport;
2734
import org.springframework.web.reactive.result.method.SyncHandlerMethodArgumentResolver;
@@ -36,6 +43,9 @@
3643
* <li>{@link ServerHttpRequest}
3744
* <li>{@link ServerHttpResponse}
3845
* <li>{@link HttpMethod}
46+
* <li>{@link Locale}
47+
* <li>{@link TimeZone}
48+
* <li>{@link ZoneId}
3949
* <li>{@link UriBuilder} or {@link UriComponentsBuilder} -- for building URL's
4050
* relative to the current request
4151
* </ul>
@@ -63,6 +73,9 @@ public boolean supportsParameter(MethodParameter parameter) {
6373
ServerHttpRequest.class.isAssignableFrom(type) ||
6474
ServerHttpResponse.class.isAssignableFrom(type) ||
6575
HttpMethod.class == type ||
76+
Locale.class == type ||
77+
TimeZone.class == type ||
78+
ZoneId.class == type ||
6679
UriBuilder.class == type || UriComponentsBuilder.class == type);
6780
}
6881

@@ -83,6 +96,19 @@ else if (ServerHttpResponse.class.isAssignableFrom(paramType)) {
8396
else if (HttpMethod.class == paramType) {
8497
return exchange.getRequest().getMethod();
8598
}
99+
else if (Locale.class == paramType) {
100+
return exchange.getLocaleContext().getLocale();
101+
}
102+
else if (TimeZone.class == paramType) {
103+
LocaleContext localeContext = exchange.getLocaleContext();
104+
TimeZone timeZone = getTimeZone(localeContext);
105+
return timeZone != null ? timeZone : TimeZone.getDefault();
106+
}
107+
else if (ZoneId.class == paramType) {
108+
LocaleContext localeContext = exchange.getLocaleContext();
109+
TimeZone timeZone = getTimeZone(localeContext);
110+
return timeZone != null ? timeZone.toZoneId() : ZoneId.systemDefault();
111+
}
86112
else if (UriBuilder.class == paramType || UriComponentsBuilder.class == paramType) {
87113
return UriComponentsBuilder.fromHttpRequest(exchange.getRequest());
88114
}
@@ -93,4 +119,13 @@ else if (UriBuilder.class == paramType || UriComponentsBuilder.class == paramTyp
93119
}
94120
}
95121

122+
@Nullable
123+
private TimeZone getTimeZone(LocaleContext localeContext) {
124+
TimeZone timeZone = null;
125+
if (localeContext instanceof TimeZoneAwareLocaleContext) {
126+
timeZone = ((TimeZoneAwareLocaleContext) localeContext).getTimeZone();
127+
}
128+
return timeZone;
129+
}
130+
96131
}

spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ServerWebExchangeArgumentResolverTests.java

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616

1717
package org.springframework.web.reactive.result.method.annotation;
1818

19+
import java.time.ZoneId;
20+
import java.util.Locale;
21+
import java.util.TimeZone;
22+
1923
import org.junit.Test;
2024
import reactor.core.publisher.Mono;
2125

@@ -60,6 +64,9 @@ public void supportsParameter() throws Exception {
6064
assertTrue(this.resolver.supportsParameter(this.testMethod.arg(ServerHttpRequest.class)));
6165
assertTrue(this.resolver.supportsParameter(this.testMethod.arg(ServerHttpResponse.class)));
6266
assertTrue(this.resolver.supportsParameter(this.testMethod.arg(HttpMethod.class)));
67+
assertTrue(this.resolver.supportsParameter(this.testMethod.arg(Locale.class)));
68+
assertTrue(this.resolver.supportsParameter(this.testMethod.arg(TimeZone.class)));
69+
assertTrue(this.resolver.supportsParameter(this.testMethod.arg(ZoneId.class)));
6370
assertTrue(this.resolver.supportsParameter(this.testMethod.arg(UriComponentsBuilder.class)));
6471
assertTrue(this.resolver.supportsParameter(this.testMethod.arg(UriBuilder.class)));
6572

@@ -81,6 +88,13 @@ public void resolveArgument() throws Exception {
8188
testResolveArgument(this.testMethod.arg(ServerHttpRequest.class), this.exchange.getRequest());
8289
testResolveArgument(this.testMethod.arg(ServerHttpResponse.class), this.exchange.getResponse());
8390
testResolveArgument(this.testMethod.arg(HttpMethod.class), HttpMethod.GET);
91+
testResolveArgument(this.testMethod.arg(TimeZone.class), TimeZone.getDefault());
92+
testResolveArgument(this.testMethod.arg(ZoneId.class), ZoneId.systemDefault());
93+
}
94+
95+
private void testResolveArgument(MethodParameter parameter, Object expected) {
96+
Mono<Object> mono = this.resolver.resolveArgument(parameter, new BindingContext(), this.exchange);
97+
assertEquals(expected, mono.block());
8498
}
8599

86100
@Test
@@ -93,10 +107,6 @@ public void resolveUriComponentsBuilder() throws Exception {
93107
assertEquals("/path/next", ((UriComponentsBuilder) value).path("/next").build().toUriString());
94108
}
95109

96-
private void testResolveArgument(MethodParameter parameter, Object expected) {
97-
Mono<Object> mono = this.resolver.resolveArgument(parameter, new BindingContext(), this.exchange);
98-
assertSame(expected, mono.block());
99-
}
100110

101111

102112
@SuppressWarnings("unused")
@@ -106,6 +116,9 @@ public void handle(
106116
ServerHttpResponse response,
107117
WebSession session,
108118
HttpMethod httpMethod,
119+
Locale locale,
120+
TimeZone timeZone,
121+
ZoneId zoneId,
109122
UriComponentsBuilder uriComponentsBuilder,
110123
UriBuilder uriBuilder,
111124
String s,

src/docs/asciidoc/web/webflux.adoc

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -873,15 +873,13 @@ Supports reactive types.
873873
|`org.springframework.http.HttpMethod`
874874
|The HTTP method of the request.
875875

876-
// TODO: not supported
877-
// |`java.util.Locale`
878-
// |The current request locale, determined by the most specific `LocaleResolver` available, in
879-
// effect, the configured `LocaleResolver`/`LocaleContextResolver`.
880-
881-
// TODO: not supported
882-
//|Java 6+: `java.util.TimeZone` +
883-
//Java 8+: `java.time.ZoneId`
884-
//|The time zone associated with the current request, as determined by a `LocaleContextResolver`.
876+
|`java.util.Locale`
877+
|The current request locale, determined by the most specific `LocaleResolver` available, in
878+
effect, the configured `LocaleResolver`/`LocaleContextResolver`.
879+
880+
|Java 6+: `java.util.TimeZone` +
881+
Java 8+: `java.time.ZoneId`
882+
|The time zone associated with the current request, as determined by a `LocaleContextResolver`.
885883

886884
|`@PathVariable`
887885
|For access to URI template variables.

0 commit comments

Comments
 (0)