Fix return value validation
Fix argument in call to applyReturnValueValidation() method in MethodValidationInterceptor.java. Method argument was passed instead of the return value of the method that was being validated. See gh-33105
This commit is contained in:
parent
100da83913
commit
976b4f3533
|
|
@ -174,7 +174,7 @@ public class MethodValidationInterceptor implements MethodInterceptor {
|
|||
Object returnValue = invocation.proceed();
|
||||
|
||||
if (this.adaptViolations) {
|
||||
this.validationAdapter.applyReturnValueValidation(target, method, null, arguments, groups);
|
||||
this.validationAdapter.applyReturnValueValidation(target, method, null, returnValue, groups);
|
||||
}
|
||||
else {
|
||||
violations = this.validationAdapter.invokeValidatorForReturnValue(target, method, returnValue, groups);
|
||||
|
|
|
|||
|
|
@ -20,8 +20,10 @@ import java.lang.annotation.Retention;
|
|||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import jakarta.validation.ValidationException;
|
||||
import jakarta.validation.ConstraintViolationException;
|
||||
import jakarta.validation.Validation;
|
||||
import jakarta.validation.Validator;
|
||||
import jakarta.validation.ValidatorFactory;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.groups.Default;
|
||||
|
|
@ -45,7 +47,9 @@ import org.springframework.scheduling.annotation.AsyncAnnotationAdvisor;
|
|||
import org.springframework.scheduling.annotation.AsyncAnnotationBeanPostProcessor;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.function.SingletonSupplier;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.validation.method.MethodValidationException;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
|
@ -66,7 +70,19 @@ class MethodValidationProxyTests {
|
|||
ProxyFactory factory = new ProxyFactory(bean);
|
||||
factory.addAdvice(new MethodValidationInterceptor());
|
||||
factory.addAdvisor(new AsyncAnnotationAdvisor());
|
||||
doTestProxyValidation((MyValidInterface<String>) factory.getProxy());
|
||||
doTestProxyValidation((MyValidInterface<String>) factory.getProxy(), ConstraintViolationException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testMethodValidationInterceptorWithAdaptConstraintViolations() {
|
||||
MyValidBean bean = new MyValidBean();
|
||||
ProxyFactory factory = new ProxyFactory(bean);
|
||||
try (ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory()) {
|
||||
factory.addAdvice(new MethodValidationInterceptor(SingletonSupplier.of(validatorFactory.getValidator()), true));
|
||||
factory.addAdvisor(new AsyncAnnotationAdvisor());
|
||||
doTestProxyValidation((MyValidInterface<String>) factory.getProxy(), MethodValidationException.class);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -79,7 +95,26 @@ class MethodValidationProxyTests {
|
|||
context.registerSingleton("aapp", AsyncAnnotationBeanPostProcessor.class, pvs);
|
||||
context.registerSingleton("bean", MyValidBean.class);
|
||||
context.refresh();
|
||||
doTestProxyValidation(context.getBean("bean", MyValidInterface.class));
|
||||
doTestProxyValidation(context.getBean("bean", MyValidInterface.class), ConstraintViolationException.class);
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testMethodValidationPostProcessorWithAdaptConstraintViolations() {
|
||||
StaticApplicationContext context = new StaticApplicationContext();
|
||||
context.registerBean(MethodValidationPostProcessor.class, () -> {
|
||||
MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();
|
||||
postProcessor.setAdaptConstraintViolations(true);
|
||||
return postProcessor;
|
||||
});
|
||||
|
||||
MutablePropertyValues pvs = new MutablePropertyValues();
|
||||
pvs.add("beforeExistingAdvisors", false);
|
||||
context.registerSingleton("aapp", AsyncAnnotationBeanPostProcessor.class, pvs);
|
||||
context.registerSingleton("bean", MyValidBean.class);
|
||||
context.refresh();
|
||||
doTestProxyValidation(context.getBean("bean", MyValidInterface.class), MethodValidationException.class);
|
||||
context.close();
|
||||
}
|
||||
|
||||
|
|
@ -90,21 +125,38 @@ class MethodValidationProxyTests {
|
|||
context.registerBean(MyValidInterface.class, () ->
|
||||
ProxyFactory.getProxy(MyValidInterface.class, new MyValidClientInterfaceMethodInterceptor()));
|
||||
context.refresh();
|
||||
doTestProxyValidation(context.getBean(MyValidInterface.class));
|
||||
doTestProxyValidation(context.getBean(MyValidInterface.class), ConstraintViolationException.class);
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testMethodValidationPostProcessorForInterfaceOnlyProxyWithAdaptConstraintViolations() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
context.registerBean(MethodValidationPostProcessor.class, () -> {
|
||||
MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();
|
||||
postProcessor.setAdaptConstraintViolations(true);
|
||||
return postProcessor;
|
||||
});
|
||||
|
||||
context.registerBean(MyValidInterface.class, () ->
|
||||
ProxyFactory.getProxy(MyValidInterface.class, new MyValidClientInterfaceMethodInterceptor()));
|
||||
context.refresh();
|
||||
doTestProxyValidation(context.getBean(MyValidInterface.class), MethodValidationException.class);
|
||||
context.close();
|
||||
}
|
||||
|
||||
@SuppressWarnings("DataFlowIssue")
|
||||
private void doTestProxyValidation(MyValidInterface<String> proxy) {
|
||||
private void doTestProxyValidation(MyValidInterface<String> proxy, Class<? extends Exception> expectedExceptionClass) {
|
||||
assertThat(proxy.myValidMethod("value", 5)).isNotNull();
|
||||
assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> proxy.myValidMethod("value", 15));
|
||||
assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> proxy.myValidMethod(null, 5));
|
||||
assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> proxy.myValidMethod("value", 0));
|
||||
assertThatExceptionOfType(expectedExceptionClass).isThrownBy(() -> proxy.myValidMethod("value", 15));
|
||||
assertThatExceptionOfType(expectedExceptionClass).isThrownBy(() -> proxy.myValidMethod(null, 5));
|
||||
assertThatExceptionOfType(expectedExceptionClass).isThrownBy(() -> proxy.myValidMethod("value", 0));
|
||||
proxy.myValidAsyncMethod("value", 5);
|
||||
assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> proxy.myValidAsyncMethod("value", 15));
|
||||
assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> proxy.myValidAsyncMethod(null, 5));
|
||||
assertThatExceptionOfType(expectedExceptionClass).isThrownBy(() -> proxy.myValidAsyncMethod("value", 15));
|
||||
assertThatExceptionOfType(expectedExceptionClass).isThrownBy(() -> proxy.myValidAsyncMethod(null, 5));
|
||||
assertThat(proxy.myGenericMethod("myValue")).isEqualTo("myValue");
|
||||
assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> proxy.myGenericMethod(null));
|
||||
assertThatExceptionOfType(expectedExceptionClass).isThrownBy(() -> proxy.myGenericMethod(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -122,6 +174,11 @@ class MethodValidationProxyTests {
|
|||
doTestLazyValidatorForMethodValidation(LazyMethodValidationConfigWithValidatorProvider.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLazyValidatorForMethodValidationWithAdaptConstraintViolations() {
|
||||
doTestLazyValidatorForMethodValidation(LazyMethodValidationConfigWithAdaptConstraintViolations.class);
|
||||
}
|
||||
|
||||
private void doTestLazyValidatorForMethodValidation(Class<?> configClass) {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
context.register(configClass, CustomValidatorBean.class, MyValidBean.class, MyValidFactoryBean.class);
|
||||
|
|
@ -278,4 +335,16 @@ class MethodValidationProxyTests {
|
|||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class LazyMethodValidationConfigWithAdaptConstraintViolations {
|
||||
|
||||
@Bean
|
||||
public static MethodValidationPostProcessor methodValidationPostProcessor(ObjectProvider<Validator> validator) {
|
||||
MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();
|
||||
postProcessor.setValidatorProvider(validator);
|
||||
postProcessor.setAdaptConstraintViolations(true);
|
||||
return postProcessor;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue