Skip to content

Commit 39e3876

Browse files
bougarsbrannen
authored andcommitted
Fix BindingResult error when ModelAttribute has custom name in WebFlux
Closes gh-28422
1 parent f771603 commit 39e3876

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ private Object getErrors(MethodParameter parameter, BindingContext context) {
8686
"Either declare the @ModelAttribute without an async wrapper type or " +
8787
"handle a WebExchangeBindException error signal through the async type.");
8888

89-
ModelAttribute ann = parameter.getParameterAnnotation(ModelAttribute.class);
89+
ModelAttribute ann = attributeParam.getParameterAnnotation(ModelAttribute.class);
9090
String name = (ann != null && StringUtils.hasText(ann.value()) ?
9191
ann.value() : Conventions.getVariableNameForParameter(attributeParam));
9292
Object errors = context.getModel().asMap().get(BindingResult.MODEL_KEY_PREFIX + name);

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

+39
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,21 @@ void resolve() {
8181
assertThat(actual).isSameAs(bindingResult);
8282
}
8383

84+
@Test
85+
void resolveOnBindingResultAndModelAttributeWithCustomValue() {
86+
BindingResult bindingResult = createBindingResult(new Foo(), "custom");
87+
this.bindingContext.getModel().asMap().put(BindingResult.MODEL_KEY_PREFIX + "custom", bindingResult);
88+
89+
ResolvableMethod testMethod = ResolvableMethod.on(getClass())
90+
.named("handleWithModelAttributeValue").build();
91+
92+
MethodParameter parameter = testMethod.arg(Errors.class);
93+
Object actual = this.resolver.resolveArgument(parameter, this.bindingContext, this.exchange)
94+
.block(Duration.ofMillis(5000));
95+
96+
assertThat(actual).isSameAs(bindingResult);
97+
}
98+
8499
private BindingResult createBindingResult(Foo target, String name) {
85100
DataBinder binder = this.bindingContext.createDataBinder(this.exchange, target, name);
86101
return binder.getBindingResult();
@@ -98,6 +113,21 @@ void resolveWithMono() {
98113
assertThat(actual).isSameAs(bindingResult);
99114
}
100115

116+
@Test
117+
void resolveWithMonoOnBindingResultAndModelAttributeWithCustomValue() {
118+
BindingResult bindingResult = createBindingResult(new Foo(), "custom");
119+
this.bindingContext.getModel().asMap().put(BindingResult.MODEL_KEY_PREFIX + "custom", Mono.just(bindingResult));
120+
121+
ResolvableMethod testMethod = ResolvableMethod.on(getClass())
122+
.named("handleWithModelAttributeValue").build();
123+
124+
MethodParameter parameter = testMethod.arg(Errors.class);
125+
Object actual = this.resolver.resolveArgument(parameter, this.bindingContext, this.exchange)
126+
.block(Duration.ofMillis(5000));
127+
128+
assertThat(actual).isSameAs(bindingResult);
129+
}
130+
101131
@Test
102132
void resolveWithMonoOnBindingResultAndModelAttribute() {
103133
MethodParameter parameter = this.testMethod.arg(BindingResult.class);
@@ -150,4 +180,13 @@ void handle(
150180
String string) {
151181
}
152182

183+
@SuppressWarnings("unused")
184+
void handleWithModelAttributeValue(
185+
@ModelAttribute("custom") Foo foo,
186+
Errors errors,
187+
@ModelAttribute Mono<Foo> fooMono,
188+
BindingResult bindingResult,
189+
Mono<Errors> errorsMono,
190+
String string) {
191+
}
153192
}

0 commit comments

Comments
 (0)