diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageReaderArgumentResolver.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageReaderArgumentResolver.java index dd2008d608..753da53b87 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageReaderArgumentResolver.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageReaderArgumentResolver.java @@ -25,6 +25,7 @@ import java.util.Set; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.core.Conventions; import org.springframework.core.MethodParameter; import org.springframework.core.ReactiveAdapter; @@ -269,7 +270,13 @@ public abstract class AbstractMessageReaderArgumentResolver extends HandlerMetho String name = Conventions.getVariableNameForParameter(param); WebExchangeDataBinder binder = binding.createDataBinder(exchange, target, name); - binder.validate(validationHints); + try { + LocaleContextHolder.setLocaleContext(exchange.getLocaleContext()); + binder.validate(validationHints); + } + finally { + LocaleContextHolder.resetLocaleContext(); + } if (binder.getBindingResult().hasErrors()) { throw new WebExchangeBindException(param, binder.getBindingResult()); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolver.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolver.java index 24a0eaf3c2..8bc38c72f4 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolver.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolver.java @@ -26,6 +26,8 @@ import reactor.core.publisher.Mono; import reactor.core.publisher.Sinks; import org.springframework.beans.BeanUtils; +import org.springframework.context.i18n.LocaleContext; +import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.core.MethodParameter; import org.springframework.core.ReactiveAdapter; import org.springframework.core.ReactiveAdapterRegistry; @@ -121,7 +123,7 @@ public class ModelAttributeMethodArgumentResolver extends HandlerMethodArgumentR return (bindingDisabled(parameter) ? Mono.empty() : bindRequestParameters(binder, exchange)) .doOnError(bindingResultSink::tryEmitError) .doOnSuccess(aVoid -> { - validateIfApplicable(binder, parameter); + validateIfApplicable(binder, parameter, exchange); BindingResult bindingResult = binder.getBindingResult(); model.put(BindingResult.MODEL_KEY_PREFIX + name, bindingResult); model.put(name, value); @@ -278,11 +280,23 @@ public class ModelAttributeMethodArgumentResolver extends HandlerMethodArgumentR return (paramTypes.length > i + 1 && Errors.class.isAssignableFrom(paramTypes[i + 1])); } - private void validateIfApplicable(WebExchangeDataBinder binder, MethodParameter parameter) { - for (Annotation ann : parameter.getParameterAnnotations()) { - Object[] validationHints = ValidationAnnotationUtils.determineValidationHints(ann); - if (validationHints != null) { - binder.validate(validationHints); + private void validateIfApplicable(WebExchangeDataBinder binder, MethodParameter parameter, ServerWebExchange exchange) { + LocaleContext localeContext = null; + try { + for (Annotation ann : parameter.getParameterAnnotations()) { + Object[] validationHints = ValidationAnnotationUtils.determineValidationHints(ann); + if (validationHints != null) { + if (localeContext == null) { + localeContext = exchange.getLocaleContext(); + LocaleContextHolder.setLocaleContext(localeContext); + } + binder.validate(validationHints); + } + } + } + finally { + if (localeContext != null) { + LocaleContextHolder.resetLocaleContext(); } } }