Conditional use of URI vars for data binding in WebFlux

This commit aligns Spring WebFlux with WebMvc in adding URI variables
conditionally if not already in the map. The idea is that data
binding is primarily through form data and query params, with URI
variables, and request headers (to be implemented next) also made
available but without shadowing existing values.

See gh-32676
This commit is contained in:
rstoyanchev
2024-06-04 15:40:38 +01:00
parent 398aae2b9a
commit 23160a43dd
2 changed files with 49 additions and 5 deletions

View File

@@ -17,16 +17,20 @@
package org.springframework.web.reactive;
import java.lang.reflect.Method;
import java.util.Map;
import jakarta.validation.Valid;
import org.junit.jupiter.api.Test;
import org.springframework.beans.testfixture.beans.TestBean;
import org.springframework.core.ResolvableType;
import org.springframework.http.MediaType;
import org.springframework.validation.Errors;
import org.springframework.validation.SmartValidator;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.support.WebExchangeDataBinder;
import org.springframework.web.testfixture.http.server.reactive.MockServerHttpRequest;
import org.springframework.web.testfixture.server.MockServerWebExchange;
@@ -64,6 +68,27 @@ class BindingContextTests {
assertThat(binder.getValidatorsToApply()).containsExactly(springValidator);
}
@Test
void uriVariablesAddedConditionally() {
MockServerHttpRequest request = MockServerHttpRequest.post("/path")
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.body("name=John&age=25");
MockServerWebExchange exchange = MockServerWebExchange.from(request);
exchange.getAttributes().put(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, Map.of("age", "26"));
TestBean testBean = new TestBean();
BindingContext bindingContext = new BindingContext(null);
WebExchangeDataBinder binder = bindingContext.createDataBinder(exchange, testBean, "testBean", null);
binder.bind(exchange).block();
assertThat(testBean.getName()).isEqualTo("John");
assertThat(testBean.getAge()).isEqualTo(25);
}
@SuppressWarnings("unused")
private void handleValidObject(@Valid Foo foo) {