diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ErrorsMethodArgumentResolver.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ErrorsMethodArgumentResolver.java index 28abd49dfd..7f6a1dea9f 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ErrorsMethodArgumentResolver.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ErrorsMethodArgumentResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,7 +33,8 @@ import org.springframework.web.server.ServerWebExchange; /** * Resolve {@link Errors} or {@link BindingResult} method arguments. - * An {@code Errors} argument is expected to appear immediately after the + * + *
An {@code Errors} argument is expected to appear immediately after the
* model attribute in the method signature.
*
* @author Rossen Stoyanchev
@@ -86,7 +87,7 @@ public class ErrorsMethodArgumentResolver extends HandlerMethodArgumentResolverS
"Either declare the @ModelAttribute without an async wrapper type or " +
"handle a WebExchangeBindException error signal through the async type.");
- ModelAttribute ann = parameter.getParameterAnnotation(ModelAttribute.class);
+ ModelAttribute ann = attributeParam.getParameterAnnotation(ModelAttribute.class);
String name = (ann != null && StringUtils.hasText(ann.value()) ?
ann.value() : Conventions.getVariableNameForParameter(attributeParam));
Object errors = context.getModel().asMap().get(BindingResult.MODEL_KEY_PREFIX + name);
diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ErrorsMethodArgumentResolverTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ErrorsMethodArgumentResolverTests.java
index 38467b7107..499a5b85da 100644
--- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ErrorsMethodArgumentResolverTests.java
+++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ErrorsMethodArgumentResolverTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -81,6 +81,20 @@ class ErrorsMethodArgumentResolverTests {
assertThat(actual).isSameAs(bindingResult);
}
+ @Test
+ void resolveOnBindingResultAndModelAttributeWithCustomName() {
+ BindingResult bindingResult = createBindingResult(new Foo(), "custom");
+ this.bindingContext.getModel().asMap().put(BindingResult.MODEL_KEY_PREFIX + "custom", bindingResult);
+
+ ResolvableMethod testMethod = ResolvableMethod.on(getClass()).named("handleWithCustomModelAttributeName").build();
+
+ MethodParameter parameter = testMethod.arg(Errors.class);
+ Object actual = this.resolver.resolveArgument(parameter, this.bindingContext, this.exchange)
+ .block(Duration.ofMillis(5000));
+
+ assertThat(actual).isSameAs(bindingResult);
+ }
+
private BindingResult createBindingResult(Foo target, String name) {
DataBinder binder = this.bindingContext.createDataBinder(this.exchange, target, name);
return binder.getBindingResult();
@@ -98,6 +112,20 @@ class ErrorsMethodArgumentResolverTests {
assertThat(actual).isSameAs(bindingResult);
}
+ @Test
+ void resolveWithMonoOnBindingResultAndModelAttributeWithCustomName() {
+ BindingResult bindingResult = createBindingResult(new Foo(), "custom");
+ this.bindingContext.getModel().asMap().put(BindingResult.MODEL_KEY_PREFIX + "custom", Mono.just(bindingResult));
+
+ ResolvableMethod testMethod = ResolvableMethod.on(getClass()).named("handleWithCustomModelAttributeName").build();
+
+ MethodParameter parameter = testMethod.arg(Errors.class);
+ Object actual = this.resolver.resolveArgument(parameter, this.bindingContext, this.exchange)
+ .block(Duration.ofMillis(5000));
+
+ assertThat(actual).isSameAs(bindingResult);
+ }
+
@Test
void resolveWithMonoOnBindingResultAndModelAttribute() {
MethodParameter parameter = this.testMethod.arg(BindingResult.class);
@@ -150,4 +178,14 @@ class ErrorsMethodArgumentResolverTests {
String string) {
}
+ @SuppressWarnings("unused")
+ void handleWithCustomModelAttributeName(
+ @ModelAttribute("custom") Foo foo,
+ Errors errors,
+ @ModelAttribute Mono