parent
36b0702c0b
commit
398aae2b9a
|
|
@ -148,13 +148,19 @@ public class WebExchangeDataBinder extends WebDataBinder {
|
||||||
|
|
||||||
protected static void addBindValue(Map<String, Object> params, String key, List<?> values) {
|
protected static void addBindValue(Map<String, Object> params, String key, List<?> values) {
|
||||||
if (!CollectionUtils.isEmpty(values)) {
|
if (!CollectionUtils.isEmpty(values)) {
|
||||||
values = values.stream()
|
if (values.size() == 1) {
|
||||||
.map(value -> value instanceof FormFieldPart formFieldPart ? formFieldPart.value() : value)
|
params.put(key, adaptBindValue(values.get(0)));
|
||||||
.toList();
|
}
|
||||||
params.put(key, values.size() == 1 ? values.get(0) : values);
|
else {
|
||||||
|
params.put(key, values.stream().map(WebExchangeDataBinder::adaptBindValue).toList());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Object adaptBindValue(Object value) {
|
||||||
|
return (value instanceof FormFieldPart part ? part.value() : value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve values from a map.
|
* Resolve values from a map.
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,11 @@
|
||||||
|
|
||||||
package org.springframework.web.reactive;
|
package org.springframework.web.reactive;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import org.springframework.core.MethodParameter;
|
|
||||||
import org.springframework.core.ResolvableType;
|
import org.springframework.core.ResolvableType;
|
||||||
import org.springframework.validation.Errors;
|
import org.springframework.validation.Errors;
|
||||||
import org.springframework.validation.SmartValidator;
|
import org.springframework.validation.SmartValidator;
|
||||||
|
|
@ -27,7 +28,6 @@ import org.springframework.validation.Validator;
|
||||||
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
||||||
import org.springframework.web.bind.WebDataBinder;
|
import org.springframework.web.bind.WebDataBinder;
|
||||||
import org.springframework.web.testfixture.http.server.reactive.MockServerHttpRequest;
|
import org.springframework.web.testfixture.http.server.reactive.MockServerHttpRequest;
|
||||||
import org.springframework.web.testfixture.method.ResolvableMethod;
|
|
||||||
import org.springframework.web.testfixture.server.MockServerWebExchange;
|
import org.springframework.web.testfixture.server.MockServerWebExchange;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
@ -40,44 +40,37 @@ import static org.mockito.BDDMockito.when;
|
||||||
class BindingContextTests {
|
class BindingContextTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void jakartaValidatorExcludedWhenMethodValidationApplicable() {
|
void jakartaValidatorExcludedWhenMethodValidationApplicable() throws Exception {
|
||||||
BindingContext bindingContext = new BindingContext(null);
|
BindingContext bindingContext = new BindingContext(null);
|
||||||
bindingContext.setMethodValidationApplicable(true);
|
bindingContext.setMethodValidationApplicable(true);
|
||||||
|
|
||||||
MethodParameter parameter = ResolvableMethod.on(BindingContextTests.class)
|
Method method = getClass().getDeclaredMethod("handleValidObject", Foo.class);
|
||||||
.named("handle").build().annotPresent(Valid.class).arg();
|
ResolvableType targetType = ResolvableType.forMethodParameter(method, 0);
|
||||||
|
|
||||||
WebDataBinder dataBinder = bindingContext.createDataBinder(
|
WebDataBinder binder = bindingContext.createDataBinder(
|
||||||
MockServerWebExchange.from(MockServerHttpRequest.get("")), new Foo(), "foo",
|
MockServerWebExchange.from(MockServerHttpRequest.get("")), new Foo(), "foo", targetType);
|
||||||
ResolvableType.forMethodParameter(parameter));
|
|
||||||
|
|
||||||
Validator springValidator = mock(Validator.class);
|
Validator springValidator = mock(Validator.class);
|
||||||
when(springValidator.supports(Foo.class)).thenReturn(true);
|
when(springValidator.supports(Foo.class)).thenReturn(true);
|
||||||
dataBinder.addValidators(springValidator);
|
binder.addValidators(springValidator);
|
||||||
|
|
||||||
LocalValidatorFactoryBean beanValidator = new LocalValidatorFactoryBean();
|
LocalValidatorFactoryBean beanValidator = new LocalValidatorFactoryBean();
|
||||||
beanValidator.afterPropertiesSet();
|
beanValidator.afterPropertiesSet();
|
||||||
dataBinder.addValidators(beanValidator);
|
binder.addValidators(beanValidator);
|
||||||
|
|
||||||
WrappedBeanValidator wrappedBeanValidator = new WrappedBeanValidator(beanValidator);
|
WrappedBeanValidator wrappedBeanValidator = new WrappedBeanValidator(beanValidator);
|
||||||
dataBinder.addValidators(wrappedBeanValidator);
|
binder.addValidators(wrappedBeanValidator);
|
||||||
|
|
||||||
assertThat(dataBinder.getValidatorsToApply()).containsExactly(springValidator);
|
assertThat(binder.getValidatorsToApply()).containsExactly(springValidator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private void handle(@Valid Foo foo) {
|
private void handleValidObject(@Valid Foo foo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class WrappedBeanValidator implements SmartValidator {
|
private record WrappedBeanValidator(jakarta.validation.Validator validator) implements SmartValidator {
|
||||||
|
|
||||||
private final jakarta.validation.Validator validator;
|
|
||||||
|
|
||||||
private WrappedBeanValidator(jakarta.validation.Validator validator) {
|
|
||||||
this.validator = validator;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supports(Class<?> clazz) {
|
public boolean supports(Class<?> clazz) {
|
||||||
|
|
@ -100,6 +93,6 @@ class BindingContextTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class Foo {}
|
private static final class Foo {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2023 the original author or authors.
|
* Copyright 2002-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -81,24 +81,29 @@ public class ExtendedServletRequestDataBinder extends ServletRequestDataBinder {
|
||||||
protected void addBindValues(MutablePropertyValues mpvs, ServletRequest request) {
|
protected void addBindValues(MutablePropertyValues mpvs, ServletRequest request) {
|
||||||
Map<String, String> uriVars = getUriVars(request);
|
Map<String, String> uriVars = getUriVars(request);
|
||||||
if (uriVars != null) {
|
if (uriVars != null) {
|
||||||
uriVars.forEach((name, value) -> {
|
uriVars.forEach((name, value) -> addValueIfNotPresent(mpvs, "URI variable", name, value));
|
||||||
if (mpvs.contains(name)) {
|
|
||||||
if (logger.isDebugEnabled()) {
|
|
||||||
logger.debug("URI variable '" + name + "' overridden by request bind value.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
mpvs.addPropertyValue(name, value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Nullable
|
@Nullable
|
||||||
private static Map<String, String> getUriVars(ServletRequest request) {
|
private static Map<String, String> getUriVars(ServletRequest request) {
|
||||||
String attr = HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE;
|
return (Map<String, String>) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
|
||||||
return (Map<String, String>) request.getAttribute(attr);
|
}
|
||||||
|
|
||||||
|
private static void addValueIfNotPresent(
|
||||||
|
MutablePropertyValues mpvs, String label, String name, @Nullable Object value) {
|
||||||
|
|
||||||
|
if (value != null) {
|
||||||
|
if (mpvs.contains(name)) {
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug(label + " '" + name + "' overridden by request bind value.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mpvs.addPropertyValue(name, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,10 +45,10 @@ class ExtendedServletRequestDataBinderTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void createBinder() {
|
void createBinder() {
|
||||||
Map<String, String> uriTemplateVars = new HashMap<>();
|
|
||||||
uriTemplateVars.put("name", "nameValue");
|
this.request.setAttribute(
|
||||||
uriTemplateVars.put("age", "25");
|
HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE,
|
||||||
request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVars);
|
Map.of("name", "nameValue", "age", "25"));
|
||||||
|
|
||||||
TestBean target = new TestBean();
|
TestBean target = new TestBean();
|
||||||
ServletRequestDataBinder binder = new ExtendedServletRequestDataBinder(target, "");
|
ServletRequestDataBinder binder = new ExtendedServletRequestDataBinder(target, "");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue