parent
a5103307c6
commit
ff97eafa4f
|
|
@ -48,7 +48,7 @@ public class ErrorsMethodArgumentResolver extends HandlerMethodArgumentResolverS
|
|||
|
||||
@Override
|
||||
public boolean supportsParameter(MethodParameter parameter) {
|
||||
return checkParameterTypeNoReactiveWrapper(parameter, Errors.class::isAssignableFrom);
|
||||
return checkParameterType(parameter, Errors.class::isAssignableFrom);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -56,25 +56,21 @@ public class ErrorsMethodArgumentResolver extends HandlerMethodArgumentResolverS
|
|||
public Mono<Object> resolveArgument(
|
||||
MethodParameter parameter, BindingContext context, ServerWebExchange exchange) {
|
||||
|
||||
String name = getModelAttributeName(parameter);
|
||||
Object errors = context.getModel().asMap().get(BindingResult.MODEL_KEY_PREFIX + name);
|
||||
Object errors = getErrors(parameter, context);
|
||||
|
||||
Mono<?> errorsMono;
|
||||
if (Mono.class.isAssignableFrom(errors.getClass())) {
|
||||
errorsMono = (Mono<?>) errors;
|
||||
return ((Mono<?>) errors).cast(Object.class);
|
||||
}
|
||||
else if (Errors.class.isAssignableFrom(errors.getClass())) {
|
||||
errorsMono = Mono.just(errors);
|
||||
return Mono.just(errors);
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException(
|
||||
"Unexpected Errors/BindingResult type: " + errors.getClass().getName());
|
||||
}
|
||||
|
||||
return errorsMono.cast(Object.class);
|
||||
}
|
||||
|
||||
private String getModelAttributeName(MethodParameter parameter) {
|
||||
private Object getErrors(MethodParameter parameter, BindingContext context) {
|
||||
|
||||
Assert.isTrue(parameter.getParameterIndex() > 0,
|
||||
"Errors argument must be immediately after a model attribute argument");
|
||||
|
|
@ -88,11 +84,17 @@ 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);
|
||||
if (ann != null && StringUtils.hasText(ann.value())) {
|
||||
return ann.value();
|
||||
}
|
||||
return Conventions.getVariableNameForParameter(attributeParam);
|
||||
ModelAttribute annot = parameter.getParameterAnnotation(ModelAttribute.class);
|
||||
String name = (annot != null && StringUtils.hasText(annot.value()) ?
|
||||
annot.value() : Conventions.getVariableNameForParameter(attributeParam));
|
||||
|
||||
Object errors = context.getModel().asMap().get(BindingResult.MODEL_KEY_PREFIX + name);
|
||||
|
||||
Assert.notNull(errors, "An Errors/BindingResult argument is expected to be declared " +
|
||||
"immediately after the @ModelAttribute argument to which it applies: " +
|
||||
parameter.getMethod());
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ package org.springframework.web.reactive.result.method.annotation;
|
|||
|
||||
import java.time.Duration;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
|
@ -40,7 +39,6 @@ import org.springframework.web.reactive.BindingContext;
|
|||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link ErrorsMethodArgumentResolver}.
|
||||
|
|
@ -69,21 +67,16 @@ public class ErrorsMethodArgumentResolverTests {
|
|||
|
||||
parameter = this.testMethod.arg(BindingResult.class);
|
||||
assertTrue(this.resolver.supportsParameter(parameter));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesNotSupport() throws Exception {
|
||||
|
||||
MethodParameter parameter = this.testMethod.arg(String.class);
|
||||
assertFalse(this.resolver.supportsParameter(parameter));
|
||||
|
||||
this.expectedException.expectMessage("ErrorsMethodArgumentResolver doesn't support reactive type wrapper");
|
||||
parameter = this.testMethod.arg(ResolvableType.forClassWithGenerics(Mono.class, Errors.class));
|
||||
this.resolver.supportsParameter(parameter);
|
||||
assertTrue(this.resolver.supportsParameter(parameter));
|
||||
|
||||
parameter = this.testMethod.arg(String.class);
|
||||
assertFalse(this.resolver.supportsParameter(parameter));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveErrors() throws Exception {
|
||||
public void resolve() throws Exception {
|
||||
|
||||
BindingResult bindingResult = createBindingResult(new Foo(), "foo");
|
||||
this.bindingContext.getModel().asMap().put(BindingResult.MODEL_KEY_PREFIX + "foo", bindingResult);
|
||||
|
|
@ -101,7 +94,7 @@ public class ErrorsMethodArgumentResolverTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void resolveErrorsWithMono() throws Exception {
|
||||
public void resolveWithMono() throws Exception {
|
||||
|
||||
BindingResult bindingResult = createBindingResult(new Foo(), "foo");
|
||||
MonoProcessor<BindingResult> monoProcessor = MonoProcessor.create();
|
||||
|
|
@ -116,7 +109,7 @@ public class ErrorsMethodArgumentResolverTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void resolveErrorsAfterMonoModelAttribute() throws Exception {
|
||||
public void resolveWithMonoOnBindingResultAndModelAttribute() throws Exception {
|
||||
|
||||
this.expectedException.expectMessage("An @ModelAttribute and an Errors/BindingResult) arguments " +
|
||||
"cannot both be declared with an async type wrapper.");
|
||||
|
|
@ -126,6 +119,17 @@ public class ErrorsMethodArgumentResolverTests {
|
|||
.block(Duration.ofMillis(5000));
|
||||
}
|
||||
|
||||
@Test // SPR-16187
|
||||
public void resolveWithBindingResultNotFound() throws Exception {
|
||||
|
||||
this.expectedException.expectMessage("An Errors/BindingResult argument is expected " +
|
||||
"to be declared immediately after the @ModelAttribute argument");
|
||||
|
||||
MethodParameter parameter = this.testMethod.arg(Errors.class);
|
||||
this.resolver.resolveArgument(parameter, this.bindingContext, this.exchange)
|
||||
.block(Duration.ofMillis(5000));
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class Foo {
|
||||
|
|
|
|||
Loading…
Reference in New Issue