Browse Source

Support @ModelAttribute(binding=false) with WebFlux

Prior to this commit, @ModelAttribute(binding=false) was honored with
Spring Web MVC but not with WebFlux.

This commit adds support for disabling binding via @ModelAttribute with
WebFlux by adding a check to resolveArgument(...) in
ModelAttributeMethodArgumentResolver.

Closes gh-26856
pull/26893/head
Sam Brannen 4 years ago
parent
commit
66cd979ce4
  1. 13
      spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolver.java
  2. 397
      spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolverTests.java

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

@ -60,6 +60,7 @@ import org.springframework.web.server.ServerWebExchange;
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
* @author Juergen Hoeller * @author Juergen Hoeller
* @author Sam Brannen
* @since 5.0 * @since 5.0
*/ */
public class ModelAttributeMethodArgumentResolver extends HandlerMethodArgumentResolverSupport { public class ModelAttributeMethodArgumentResolver extends HandlerMethodArgumentResolverSupport {
@ -117,7 +118,7 @@ public class ModelAttributeMethodArgumentResolver extends HandlerMethodArgumentR
return valueMono.flatMap(value -> { return valueMono.flatMap(value -> {
WebExchangeDataBinder binder = context.createDataBinder(exchange, value, name); WebExchangeDataBinder binder = context.createDataBinder(exchange, value, name);
return bindRequestParameters(binder, exchange) return (bindingDisabled(parameter) ? Mono.empty() : bindRequestParameters(binder, exchange))
.doOnError(bindingResultSink::tryEmitError) .doOnError(bindingResultSink::tryEmitError)
.doOnSuccess(aVoid -> { .doOnSuccess(aVoid -> {
validateIfApplicable(binder, parameter); validateIfApplicable(binder, parameter);
@ -143,6 +144,16 @@ public class ModelAttributeMethodArgumentResolver extends HandlerMethodArgumentR
}); });
} }
/**
* Determine if binding should be disabled for the supplied {@link MethodParameter},
* based on the {@link ModelAttribute#binding} annotation attribute.
* @since 5.3.7
*/
private boolean bindingDisabled(MethodParameter parameter) {
ModelAttribute modelAttribute = parameter.getParameterAnnotation(ModelAttribute.class);
return (modelAttribute != null && !modelAttribute.binding());
}
/** /**
* Extension point to bind the request to the target object. * Extension point to bind the request to the target object.
* @param binder the data binder instance to use for the binding * @param binder the data binder instance to use for the binding

397
spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolverTests.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2020 the original author or authors. * Copyright 2002-2021 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.
@ -21,6 +21,8 @@ import java.time.Duration;
import java.util.Map; import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
import javax.validation.constraints.NotEmpty;
import io.reactivex.rxjava3.core.Single; import io.reactivex.rxjava3.core.Single;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -49,16 +51,17 @@ import static org.assertj.core.api.Assertions.assertThat;
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
* @author Juergen Hoeller * @author Juergen Hoeller
* @author Sam Brannen
*/ */
public class ModelAttributeMethodArgumentResolverTests { class ModelAttributeMethodArgumentResolverTests {
private BindingContext bindContext; private final ResolvableMethod testMethod = ResolvableMethod.on(getClass()).named("handle").build();
private ResolvableMethod testMethod = ResolvableMethod.on(getClass()).named("handle").build(); private BindingContext bindContext;
@BeforeEach @BeforeEach
public void setup() throws Exception { void setup() {
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
validator.afterPropertiesSet(); validator.afterPropertiesSet();
ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer(); ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer();
@ -68,32 +71,38 @@ public class ModelAttributeMethodArgumentResolverTests {
@Test @Test
public void supports() throws Exception { void supports() {
ModelAttributeMethodArgumentResolver resolver = ModelAttributeMethodArgumentResolver resolver =
new ModelAttributeMethodArgumentResolver(ReactiveAdapterRegistry.getSharedInstance(), false); new ModelAttributeMethodArgumentResolver(ReactiveAdapterRegistry.getSharedInstance(), false);
MethodParameter param = this.testMethod.annotPresent(ModelAttribute.class).arg(Foo.class); MethodParameter param = this.testMethod.annotPresent(ModelAttribute.class).arg(Pojo.class);
assertThat(resolver.supportsParameter(param)).isTrue(); assertThat(resolver.supportsParameter(param)).isTrue();
param = this.testMethod.annotPresent(ModelAttribute.class).arg(Mono.class, Foo.class); param = this.testMethod.annotPresent(ModelAttribute.class).arg(NonBindingPojo.class);
assertThat(resolver.supportsParameter(param)).isTrue(); assertThat(resolver.supportsParameter(param)).isTrue();
param = this.testMethod.annotNotPresent(ModelAttribute.class).arg(Foo.class); param = this.testMethod.annotPresent(ModelAttribute.class).arg(Mono.class, Pojo.class);
assertThat(resolver.supportsParameter(param)).isTrue();
param = this.testMethod.annotPresent(ModelAttribute.class).arg(Mono.class, NonBindingPojo.class);
assertThat(resolver.supportsParameter(param)).isTrue();
param = this.testMethod.annotNotPresent(ModelAttribute.class).arg(Pojo.class);
assertThat(resolver.supportsParameter(param)).isFalse(); assertThat(resolver.supportsParameter(param)).isFalse();
param = this.testMethod.annotNotPresent(ModelAttribute.class).arg(Mono.class, Foo.class); param = this.testMethod.annotNotPresent(ModelAttribute.class).arg(Mono.class, Pojo.class);
assertThat(resolver.supportsParameter(param)).isFalse(); assertThat(resolver.supportsParameter(param)).isFalse();
} }
@Test @Test
public void supportsWithDefaultResolution() throws Exception { void supportsWithDefaultResolution() {
ModelAttributeMethodArgumentResolver resolver = ModelAttributeMethodArgumentResolver resolver =
new ModelAttributeMethodArgumentResolver(ReactiveAdapterRegistry.getSharedInstance(), true); new ModelAttributeMethodArgumentResolver(ReactiveAdapterRegistry.getSharedInstance(), true);
MethodParameter param = this.testMethod.annotNotPresent(ModelAttribute.class).arg(Foo.class); MethodParameter param = this.testMethod.annotNotPresent(ModelAttribute.class).arg(Pojo.class);
assertThat(resolver.supportsParameter(param)).isTrue(); assertThat(resolver.supportsParameter(param)).isTrue();
param = this.testMethod.annotNotPresent(ModelAttribute.class).arg(Mono.class, Foo.class); param = this.testMethod.annotNotPresent(ModelAttribute.class).arg(Mono.class, Pojo.class);
assertThat(resolver.supportsParameter(param)).isTrue(); assertThat(resolver.supportsParameter(param)).isTrue();
param = this.testMethod.annotNotPresent(ModelAttribute.class).arg(String.class); param = this.testMethod.annotNotPresent(ModelAttribute.class).arg(String.class);
@ -104,204 +113,286 @@ public class ModelAttributeMethodArgumentResolverTests {
} }
@Test @Test
public void createAndBind() throws Exception { void createAndBind() throws Exception {
testBindFoo("foo", this.testMethod.annotPresent(ModelAttribute.class).arg(Foo.class), value -> { testBindPojo("pojo", this.testMethod.annotPresent(ModelAttribute.class).arg(Pojo.class), value -> {
assertThat(value.getClass()).isEqualTo(Foo.class); assertThat(value.getClass()).isEqualTo(Pojo.class);
return (Foo) value; return (Pojo) value;
}); });
} }
@Test @Test
public void createAndBindToMono() throws Exception { void createAndBindToMono() throws Exception {
MethodParameter parameter = this.testMethod MethodParameter parameter = this.testMethod
.annotNotPresent(ModelAttribute.class).arg(Mono.class, Foo.class); .annotNotPresent(ModelAttribute.class).arg(Mono.class, Pojo.class);
testBindFoo("fooMono", parameter, mono -> { testBindPojo("pojoMono", parameter, mono -> {
boolean condition = mono instanceof Mono; assertThat(mono).isInstanceOf(Mono.class);
assertThat(condition).as(mono.getClass().getName()).isTrue();
Object value = ((Mono<?>) mono).block(Duration.ofSeconds(5)); Object value = ((Mono<?>) mono).block(Duration.ofSeconds(5));
assertThat(value.getClass()).isEqualTo(Foo.class); assertThat(value.getClass()).isEqualTo(Pojo.class);
return (Foo) value; return (Pojo) value;
}); });
} }
@Test @Test
public void createAndBindToSingle() throws Exception { void createAndBindToSingle() throws Exception {
MethodParameter parameter = this.testMethod MethodParameter parameter = this.testMethod
.annotPresent(ModelAttribute.class).arg(Single.class, Foo.class); .annotPresent(ModelAttribute.class).arg(Single.class, Pojo.class);
testBindFoo("fooSingle", parameter, single -> { testBindPojo("pojoSingle", parameter, single -> {
boolean condition = single instanceof Single; assertThat(single).isInstanceOf(Single.class);
assertThat(condition).as(single.getClass().getName()).isTrue();
Object value = ((Single<?>) single).blockingGet(); Object value = ((Single<?>) single).blockingGet();
assertThat(value.getClass()).isEqualTo(Foo.class); assertThat(value.getClass()).isEqualTo(Pojo.class);
return (Foo) value; return (Pojo) value;
}); });
} }
@Test @Test
public void bindExisting() throws Exception { void createButDoNotBind() throws Exception {
Foo foo = new Foo(); MethodParameter parameter =
foo.setName("Jim"); this.testMethod.annotPresent(ModelAttribute.class).arg(NonBindingPojo.class);
this.bindContext.getModel().addAttribute(foo);
createButDoNotBindToPojo("nonBindingPojo", parameter, value -> {
MethodParameter parameter = this.testMethod.annotNotPresent(ModelAttribute.class).arg(Foo.class); assertThat(value).isInstanceOf(NonBindingPojo.class);
testBindFoo("foo", parameter, value -> { return (NonBindingPojo) value;
assertThat(value.getClass()).isEqualTo(Foo.class);
return (Foo) value;
}); });
}
assertThat(this.bindContext.getModel().asMap().get("foo")).isSameAs(foo); @Test
void createButDoNotBindToMono() throws Exception {
MethodParameter parameter =
this.testMethod.annotPresent(ModelAttribute.class).arg(Mono.class, NonBindingPojo.class);
createButDoNotBindToPojo("nonBindingPojoMono", parameter, value -> {
assertThat(value).isInstanceOf(Mono.class);
Object extractedValue = ((Mono<?>) value).block(Duration.ofSeconds(5));
assertThat(extractedValue).isInstanceOf(NonBindingPojo.class);
return (NonBindingPojo) extractedValue;
});
} }
@Test @Test
public void bindExistingMono() throws Exception { void createButDoNotBindToSingle() throws Exception {
Foo foo = new Foo(); MethodParameter parameter =
foo.setName("Jim"); this.testMethod.annotPresent(ModelAttribute.class).arg(Single.class, NonBindingPojo.class);
this.bindContext.getModel().addAttribute("fooMono", Mono.just(foo));
createButDoNotBindToPojo("nonBindingPojoSingle", parameter, value -> {
MethodParameter parameter = this.testMethod.annotNotPresent(ModelAttribute.class).arg(Foo.class); assertThat(value).isInstanceOf(Single.class);
testBindFoo("foo", parameter, value -> { Object extractedValue = ((Single<?>) value).blockingGet();
assertThat(value.getClass()).isEqualTo(Foo.class); assertThat(extractedValue).isInstanceOf(NonBindingPojo.class);
return (Foo) value; return (NonBindingPojo) extractedValue;
}); });
}
private void createButDoNotBindToPojo(String modelKey, MethodParameter methodParameter,
Function<Object, NonBindingPojo> valueExtractor) throws Exception {
Object value = createResolver()
.resolveArgument(methodParameter, this.bindContext, postForm("name=Enigma"))
.block(Duration.ZERO);
NonBindingPojo nonBindingPojo = valueExtractor.apply(value);
assertThat(nonBindingPojo).isNotNull();
assertThat(nonBindingPojo.getName()).isNull();
assertThat(this.bindContext.getModel().asMap().get("foo")).isSameAs(foo); String bindingResultKey = BindingResult.MODEL_KEY_PREFIX + modelKey;
Map<String, Object> model = bindContext.getModel().asMap();
assertThat(model).hasSize(2);
assertThat(model.get(modelKey)).isSameAs(nonBindingPojo);
assertThat(model.get(bindingResultKey)).isInstanceOf(BindingResult.class);
} }
@Test @Test
public void bindExistingSingle() throws Exception { void bindExisting() throws Exception {
Foo foo = new Foo(); Pojo pojo = new Pojo();
foo.setName("Jim"); pojo.setName("Jim");
this.bindContext.getModel().addAttribute("fooSingle", Single.just(foo)); this.bindContext.getModel().addAttribute(pojo);
MethodParameter parameter = this.testMethod.annotNotPresent(ModelAttribute.class).arg(Foo.class); MethodParameter parameter = this.testMethod.annotNotPresent(ModelAttribute.class).arg(Pojo.class);
testBindFoo("foo", parameter, value -> { testBindPojo("pojo", parameter, value -> {
assertThat(value.getClass()).isEqualTo(Foo.class); assertThat(value.getClass()).isEqualTo(Pojo.class);
return (Foo) value; return (Pojo) value;
}); });
assertThat(this.bindContext.getModel().asMap().get("foo")).isSameAs(foo); assertThat(this.bindContext.getModel().asMap().get("pojo")).isSameAs(pojo);
} }
@Test @Test
public void bindExistingMonoToMono() throws Exception { void bindExistingMono() throws Exception {
Foo foo = new Foo(); Pojo pojo = new Pojo();
foo.setName("Jim"); pojo.setName("Jim");
String modelKey = "fooMono"; this.bindContext.getModel().addAttribute("pojoMono", Mono.just(pojo));
this.bindContext.getModel().addAttribute(modelKey, Mono.just(foo));
MethodParameter parameter = this.testMethod.annotNotPresent(ModelAttribute.class).arg(Pojo.class);
testBindPojo("pojo", parameter, value -> {
assertThat(value.getClass()).isEqualTo(Pojo.class);
return (Pojo) value;
});
assertThat(this.bindContext.getModel().asMap().get("pojo")).isSameAs(pojo);
}
@Test
void bindExistingSingle() throws Exception {
Pojo pojo = new Pojo();
pojo.setName("Jim");
this.bindContext.getModel().addAttribute("pojoSingle", Single.just(pojo));
MethodParameter parameter = this.testMethod.annotNotPresent(ModelAttribute.class).arg(Pojo.class);
testBindPojo("pojo", parameter, value -> {
assertThat(value.getClass()).isEqualTo(Pojo.class);
return (Pojo) value;
});
assertThat(this.bindContext.getModel().asMap().get("pojo")).isSameAs(pojo);
}
@Test
void bindExistingMonoToMono() throws Exception {
Pojo pojo = new Pojo();
pojo.setName("Jim");
String modelKey = "pojoMono";
this.bindContext.getModel().addAttribute(modelKey, Mono.just(pojo));
MethodParameter parameter = this.testMethod MethodParameter parameter = this.testMethod
.annotNotPresent(ModelAttribute.class).arg(Mono.class, Foo.class); .annotNotPresent(ModelAttribute.class).arg(Mono.class, Pojo.class);
testBindFoo(modelKey, parameter, mono -> { testBindPojo(modelKey, parameter, mono -> {
boolean condition = mono instanceof Mono; assertThat(mono).isInstanceOf(Mono.class);
assertThat(condition).as(mono.getClass().getName()).isTrue();
Object value = ((Mono<?>) mono).block(Duration.ofSeconds(5)); Object value = ((Mono<?>) mono).block(Duration.ofSeconds(5));
assertThat(value.getClass()).isEqualTo(Foo.class); assertThat(value.getClass()).isEqualTo(Pojo.class);
return (Foo) value; return (Pojo) value;
}); });
} }
private void testBindFoo(String modelKey, MethodParameter param, Function<Object, Foo> valueExtractor) private void testBindPojo(String modelKey, MethodParameter param, Function<Object, Pojo> valueExtractor)
throws Exception { throws Exception {
Object value = createResolver() Object value = createResolver()
.resolveArgument(param, this.bindContext, postForm("name=Robert&age=25")) .resolveArgument(param, this.bindContext, postForm("name=Robert&age=25"))
.block(Duration.ZERO); .block(Duration.ZERO);
Foo foo = valueExtractor.apply(value); Pojo pojo = valueExtractor.apply(value);
assertThat(foo.getName()).isEqualTo("Robert"); assertThat(pojo.getName()).isEqualTo("Robert");
assertThat(foo.getAge()).isEqualTo(25); assertThat(pojo.getAge()).isEqualTo(25);
String bindingResultKey = BindingResult.MODEL_KEY_PREFIX + modelKey; String bindingResultKey = BindingResult.MODEL_KEY_PREFIX + modelKey;
Map<String, Object> map = bindContext.getModel().asMap(); Map<String, Object> model = bindContext.getModel().asMap();
assertThat(map.size()).as(map.toString()).isEqualTo(2); assertThat(model).hasSize(2);
assertThat(map.get(modelKey)).isSameAs(foo); assertThat(model.get(modelKey)).isSameAs(pojo);
assertThat(map.get(bindingResultKey)).isNotNull(); assertThat(model.get(bindingResultKey)).isInstanceOf(BindingResult.class);
boolean condition = map.get(bindingResultKey) instanceof BindingResult;
assertThat(condition).isTrue();
} }
@Test @Test
public void validationError() throws Exception { void validationErrorForPojo() throws Exception {
MethodParameter parameter = this.testMethod.annotNotPresent(ModelAttribute.class).arg(Foo.class); MethodParameter parameter = this.testMethod.annotNotPresent(ModelAttribute.class).arg(Pojo.class);
testValidationError(parameter, Function.identity()); testValidationError(parameter, Function.identity());
} }
@Test @Test
public void validationErrorToMono() throws Exception { void validationErrorForMono() throws Exception {
MethodParameter parameter = this.testMethod MethodParameter parameter = this.testMethod
.annotNotPresent(ModelAttribute.class).arg(Mono.class, Foo.class); .annotNotPresent(ModelAttribute.class).arg(Mono.class, Pojo.class);
testValidationError(parameter, testValidationError(parameter,
resolvedArgumentMono -> { resolvedArgumentMono -> {
Object value = resolvedArgumentMono.block(Duration.ofSeconds(5)); Object value = resolvedArgumentMono.block(Duration.ofSeconds(5));
assertThat(value).isNotNull(); assertThat(value).isInstanceOf(Mono.class);
boolean condition = value instanceof Mono;
assertThat(condition).isTrue();
return (Mono<?>) value; return (Mono<?>) value;
}); });
} }
@Test @Test
public void validationErrorToSingle() throws Exception { void validationErrorForSingle() throws Exception {
MethodParameter parameter = this.testMethod MethodParameter parameter = this.testMethod
.annotPresent(ModelAttribute.class).arg(Single.class, Foo.class); .annotPresent(ModelAttribute.class).arg(Single.class, Pojo.class);
testValidationError(parameter, testValidationError(parameter,
resolvedArgumentMono -> { resolvedArgumentMono -> {
Object value = resolvedArgumentMono.block(Duration.ofSeconds(5)); Object value = resolvedArgumentMono.block(Duration.ofSeconds(5));
assertThat(value).isNotNull(); assertThat(value).isInstanceOf(Single.class);
boolean condition = value instanceof Single;
assertThat(condition).isTrue();
return Mono.from(((Single<?>) value).toFlowable()); return Mono.from(((Single<?>) value).toFlowable());
}); });
} }
private void testValidationError(MethodParameter param, Function<Mono<?>, Mono<?>> valueMonoExtractor) @Test
void validationErrorWithoutBindingForPojo() throws Exception {
MethodParameter parameter = this.testMethod.annotPresent(ModelAttribute.class).arg(ValidatedPojo.class);
testValidationErrorWithoutBinding(parameter, Function.identity());
}
@Test
void validationErrorWithoutBindingForMono() throws Exception {
MethodParameter parameter = this.testMethod.annotPresent(ModelAttribute.class).arg(Mono.class, ValidatedPojo.class);
testValidationErrorWithoutBinding(parameter, resolvedArgumentMono -> {
Object value = resolvedArgumentMono.block(Duration.ofSeconds(5));
assertThat(value).isInstanceOf(Mono.class);
return (Mono<?>) value;
});
}
@Test
void validationErrorWithoutBindingForSingle() throws Exception {
MethodParameter parameter = this.testMethod.annotPresent(ModelAttribute.class).arg(Single.class, ValidatedPojo.class);
testValidationErrorWithoutBinding(parameter, resolvedArgumentMono -> {
Object value = resolvedArgumentMono.block(Duration.ofSeconds(5));
assertThat(value).isInstanceOf(Single.class);
return Mono.from(((Single<?>) value).toFlowable());
});
}
private void testValidationError(MethodParameter parameter, Function<Mono<?>, Mono<?>> valueMonoExtractor)
throws URISyntaxException {
testValidationError(parameter, valueMonoExtractor, "age=invalid", "age", "invalid");
}
private void testValidationErrorWithoutBinding(MethodParameter parameter, Function<Mono<?>, Mono<?>> valueMonoExtractor)
throws URISyntaxException { throws URISyntaxException {
ServerWebExchange exchange = postForm("age=invalid"); testValidationError(parameter, valueMonoExtractor, "name=Enigma", "name", null);
Mono<?> mono = createResolver().resolveArgument(param, this.bindContext, exchange); }
private void testValidationError(MethodParameter param, Function<Mono<?>, Mono<?>> valueMonoExtractor,
String formData, String field, String rejectedValue) throws URISyntaxException {
Mono<?> mono = createResolver().resolveArgument(param, this.bindContext, postForm(formData));
mono = valueMonoExtractor.apply(mono); mono = valueMonoExtractor.apply(mono);
StepVerifier.create(mono) StepVerifier.create(mono)
.consumeErrorWith(ex -> { .consumeErrorWith(ex -> {
boolean condition = ex instanceof WebExchangeBindException; assertThat(ex).isInstanceOf(WebExchangeBindException.class);
assertThat(condition).isTrue();
WebExchangeBindException bindException = (WebExchangeBindException) ex; WebExchangeBindException bindException = (WebExchangeBindException) ex;
assertThat(bindException.getErrorCount()).isEqualTo(1); assertThat(bindException.getErrorCount()).isEqualTo(1);
assertThat(bindException.hasFieldErrors("age")).isTrue(); assertThat(bindException.hasFieldErrors(field)).isTrue();
assertThat(bindException.getFieldError(field).getRejectedValue()).isEqualTo(rejectedValue);
}) })
.verify(); .verify();
} }
@Test @Test
public void bindDataClass() throws Exception { void bindDataClass() throws Exception {
testBindBar(this.testMethod.annotNotPresent(ModelAttribute.class).arg(Bar.class)); MethodParameter parameter = this.testMethod.annotNotPresent(ModelAttribute.class).arg(DataClass.class);
}
private void testBindBar(MethodParameter param) throws Exception {
Object value = createResolver() Object value = createResolver()
.resolveArgument(param, this.bindContext, postForm("name=Robert&age=25&count=1")) .resolveArgument(parameter, this.bindContext, postForm("name=Robert&age=25&count=1"))
.block(Duration.ZERO); .block(Duration.ZERO);
Bar bar = (Bar) value; DataClass dataClass = (DataClass) value;
assertThat(bar.getName()).isEqualTo("Robert"); assertThat(dataClass.getName()).isEqualTo("Robert");
assertThat(bar.getAge()).isEqualTo(25); assertThat(dataClass.getAge()).isEqualTo(25);
assertThat(bar.getCount()).isEqualTo(1); assertThat(dataClass.getCount()).isEqualTo(1);
String key = "bar"; String modelKey = "dataClass";
String bindingResultKey = BindingResult.MODEL_KEY_PREFIX + key; String bindingResultKey = BindingResult.MODEL_KEY_PREFIX + modelKey;
Map<String, Object> map = bindContext.getModel().asMap(); Map<String, Object> model = bindContext.getModel().asMap();
assertThat(map.size()).as(map.toString()).isEqualTo(2); assertThat(model).hasSize(2);
assertThat(map.get(key)).isSameAs(bar); assertThat(model.get(modelKey)).isSameAs(dataClass);
assertThat(map.get(bindingResultKey)).isNotNull(); assertThat(model.get(bindingResultKey)).isInstanceOf(BindingResult.class);
boolean condition = map.get(bindingResultKey) instanceof BindingResult;
assertThat(condition).isTrue();
} }
// TODO: SPR-15871, SPR-15542 // TODO: SPR-15871, SPR-15542
@ -320,31 +411,30 @@ public class ModelAttributeMethodArgumentResolverTests {
@SuppressWarnings("unused") @SuppressWarnings("unused")
void handle( void handle(
@ModelAttribute @Validated Foo foo, @ModelAttribute @Validated Pojo pojo,
@ModelAttribute @Validated Mono<Foo> mono, @ModelAttribute @Validated Mono<Pojo> mono,
@ModelAttribute @Validated Single<Foo> single, @ModelAttribute @Validated Single<Pojo> single,
Foo fooNotAnnotated, @ModelAttribute(binding = false) NonBindingPojo nonBindingPojo,
@ModelAttribute(binding = false) Mono<NonBindingPojo> monoNonBindingPojo,
@ModelAttribute(binding = false) Single<NonBindingPojo> singleNonBindingPojo,
@ModelAttribute(binding = false) @Validated ValidatedPojo validatedPojo,
@ModelAttribute(binding = false) @Validated Mono<ValidatedPojo> monoValidatedPojo,
@ModelAttribute(binding = false) @Validated Single<ValidatedPojo> singleValidatedPojo,
Pojo pojoNotAnnotated,
String stringNotAnnotated, String stringNotAnnotated,
Mono<Foo> monoNotAnnotated, Mono<Pojo> monoNotAnnotated,
Mono<String> monoStringNotAnnotated, Mono<String> monoStringNotAnnotated,
Bar barNotAnnotated) { DataClass dataClassNotAnnotated) {
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
private static class Foo { private static class Pojo {
private String name; private String name;
private int age; private int age;
public Foo() {
}
public Foo(String name) {
this.name = name;
}
public String getName() { public String getName() {
return name; return name;
} }
@ -364,7 +454,48 @@ public class ModelAttributeMethodArgumentResolverTests {
@SuppressWarnings("unused") @SuppressWarnings("unused")
private static class Bar { private static class NonBindingPojo {
private String name;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "NonBindingPojo [name=" + name + "]";
}
}
@SuppressWarnings("unused")
private static class ValidatedPojo {
@NotEmpty
private String name;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "ValidatedPojo [name=" + name + "]";
}
}
@SuppressWarnings("unused")
private static class DataClass {
private final String name; private final String name;
@ -372,7 +503,7 @@ public class ModelAttributeMethodArgumentResolverTests {
private int count; private int count;
public Bar(String name, int age) { public DataClass(String name, int age) {
this.name = name; this.name = name;
this.age = age; this.age = age;
} }

Loading…
Cancel
Save