Temporarily set LocaleContextHolder to provide validation message interpolator with locale context (fixes SPR-17231).

This commit is contained in:
Boris Fox 2022-07-01 17:31:38 +10:00 committed by rstoyanchev
parent f5c1e2ffa1
commit 72926c29f9
2 changed files with 28 additions and 7 deletions

View File

@ -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());
}

View File

@ -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();
}
}
}