Skip to content

Commit 72926c2

Browse files
borisfox73rstoyanchev
authored andcommitted
Temporarily set LocaleContextHolder to provide validation message interpolator with locale context (fixes SPR-17231).
1 parent f5c1e2f commit 72926c2

File tree

2 files changed

+28
-7
lines changed

2 files changed

+28
-7
lines changed

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import reactor.core.publisher.Flux;
2626
import reactor.core.publisher.Mono;
2727

28+
import org.springframework.context.i18n.LocaleContextHolder;
2829
import org.springframework.core.Conventions;
2930
import org.springframework.core.MethodParameter;
3031
import org.springframework.core.ReactiveAdapter;
@@ -269,7 +270,13 @@ private void validate(Object target, Object[] validationHints, MethodParameter p
269270

270271
String name = Conventions.getVariableNameForParameter(param);
271272
WebExchangeDataBinder binder = binding.createDataBinder(exchange, target, name);
272-
binder.validate(validationHints);
273+
try {
274+
LocaleContextHolder.setLocaleContext(exchange.getLocaleContext());
275+
binder.validate(validationHints);
276+
}
277+
finally {
278+
LocaleContextHolder.resetLocaleContext();
279+
}
273280
if (binder.getBindingResult().hasErrors()) {
274281
throw new WebExchangeBindException(param, binder.getBindingResult());
275282
}

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

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
import reactor.core.publisher.Sinks;
2727

2828
import org.springframework.beans.BeanUtils;
29+
import org.springframework.context.i18n.LocaleContext;
30+
import org.springframework.context.i18n.LocaleContextHolder;
2931
import org.springframework.core.MethodParameter;
3032
import org.springframework.core.ReactiveAdapter;
3133
import org.springframework.core.ReactiveAdapterRegistry;
@@ -121,7 +123,7 @@ public Mono<Object> resolveArgument(
121123
return (bindingDisabled(parameter) ? Mono.empty() : bindRequestParameters(binder, exchange))
122124
.doOnError(bindingResultSink::tryEmitError)
123125
.doOnSuccess(aVoid -> {
124-
validateIfApplicable(binder, parameter);
126+
validateIfApplicable(binder, parameter, exchange);
125127
BindingResult bindingResult = binder.getBindingResult();
126128
model.put(BindingResult.MODEL_KEY_PREFIX + name, bindingResult);
127129
model.put(name, value);
@@ -278,11 +280,23 @@ private boolean hasErrorsArgument(MethodParameter parameter) {
278280
return (paramTypes.length > i + 1 && Errors.class.isAssignableFrom(paramTypes[i + 1]));
279281
}
280282

281-
private void validateIfApplicable(WebExchangeDataBinder binder, MethodParameter parameter) {
282-
for (Annotation ann : parameter.getParameterAnnotations()) {
283-
Object[] validationHints = ValidationAnnotationUtils.determineValidationHints(ann);
284-
if (validationHints != null) {
285-
binder.validate(validationHints);
283+
private void validateIfApplicable(WebExchangeDataBinder binder, MethodParameter parameter, ServerWebExchange exchange) {
284+
LocaleContext localeContext = null;
285+
try {
286+
for (Annotation ann : parameter.getParameterAnnotations()) {
287+
Object[] validationHints = ValidationAnnotationUtils.determineValidationHints(ann);
288+
if (validationHints != null) {
289+
if (localeContext == null) {
290+
localeContext = exchange.getLocaleContext();
291+
LocaleContextHolder.setLocaleContext(localeContext);
292+
}
293+
binder.validate(validationHints);
294+
}
295+
}
296+
}
297+
finally {
298+
if (localeContext != null) {
299+
LocaleContextHolder.resetLocaleContext();
286300
}
287301
}
288302
}

0 commit comments

Comments
 (0)