diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationInterceptor.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationInterceptor.java index fb791ae5f3b8..50236152705b 100644 --- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationInterceptor.java +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationInterceptor.java @@ -174,7 +174,7 @@ public Object invoke(MethodInvocation invocation) throws Throwable { 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); diff --git a/spring-context/src/test/java/org/springframework/validation/beanvalidation/MethodValidationProxyTests.java b/spring-context/src/test/java/org/springframework/validation/beanvalidation/MethodValidationProxyTests.java index 50bbdecdbfef..a058f2c24112 100644 --- a/spring-context/src/test/java/org/springframework/validation/beanvalidation/MethodValidationProxyTests.java +++ b/spring-context/src/test/java/org/springframework/validation/beanvalidation/MethodValidationProxyTests.java @@ -20,7 +20,8 @@ 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.constraints.Max; import jakarta.validation.constraints.NotNull; @@ -28,6 +29,8 @@ import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import org.springframework.aop.framework.ProxyFactory; import org.springframework.beans.MutablePropertyValues; @@ -46,6 +49,7 @@ import org.springframework.util.ClassUtils; import org.springframework.util.ReflectionUtils; 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; @@ -59,27 +63,39 @@ */ class MethodValidationProxyTests { - @Test + @ParameterizedTest + @ValueSource(booleans = {true, false}) @SuppressWarnings("unchecked") - public void testMethodValidationInterceptor() { + void testMethodValidationInterceptor(boolean adaptViolations) { MyValidBean bean = new MyValidBean(); ProxyFactory factory = new ProxyFactory(bean); - factory.addAdvice(new MethodValidationInterceptor()); + factory.addAdvice(adaptViolations ? + new MethodValidationInterceptor(() -> Validation.buildDefaultValidatorFactory().getValidator(), true) : + new MethodValidationInterceptor()); factory.addAdvisor(new AsyncAnnotationAdvisor()); - doTestProxyValidation((MyValidInterface) factory.getProxy()); + doTestProxyValidation((MyValidInterface) factory.getProxy(), + (adaptViolations ? MethodValidationException.class : ConstraintViolationException.class)); } - @Test + @ParameterizedTest + @ValueSource(booleans = {true, false}) @SuppressWarnings("unchecked") - public void testMethodValidationPostProcessor() { + void testMethodValidationPostProcessor(boolean adaptViolations) { StaticApplicationContext context = new StaticApplicationContext(); - context.registerSingleton("mvpp", MethodValidationPostProcessor.class); + context.registerBean(MethodValidationPostProcessor.class, adaptViolations ? + () -> { + MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor(); + postProcessor.setAdaptConstraintViolations(true); + return postProcessor; + } : + MethodValidationPostProcessor::new); 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)); + doTestProxyValidation(context.getBean("bean", MyValidInterface.class), + adaptViolations ? MethodValidationException.class : ConstraintViolationException.class); context.close(); } @@ -91,21 +107,21 @@ public void testMethodValidationPostProcessorForInterfaceOnlyProxy() { 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(); } @SuppressWarnings("DataFlowIssue") - private void doTestProxyValidation(MyValidInterface proxy) { + private void doTestProxyValidation(MyValidInterface proxy, Class 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