|
|
|
@ -20,7 +20,8 @@ import java.lang.annotation.Retention; |
|
|
|
import java.lang.annotation.RetentionPolicy; |
|
|
|
import java.lang.annotation.RetentionPolicy; |
|
|
|
import java.lang.reflect.Method; |
|
|
|
import java.lang.reflect.Method; |
|
|
|
|
|
|
|
|
|
|
|
import jakarta.validation.ValidationException; |
|
|
|
import jakarta.validation.ConstraintViolationException; |
|
|
|
|
|
|
|
import jakarta.validation.Validation; |
|
|
|
import jakarta.validation.Validator; |
|
|
|
import jakarta.validation.Validator; |
|
|
|
import jakarta.validation.constraints.Max; |
|
|
|
import jakarta.validation.constraints.Max; |
|
|
|
import jakarta.validation.constraints.NotNull; |
|
|
|
import jakarta.validation.constraints.NotNull; |
|
|
|
@ -28,6 +29,8 @@ import jakarta.validation.groups.Default; |
|
|
|
import org.aopalliance.intercept.MethodInterceptor; |
|
|
|
import org.aopalliance.intercept.MethodInterceptor; |
|
|
|
import org.aopalliance.intercept.MethodInvocation; |
|
|
|
import org.aopalliance.intercept.MethodInvocation; |
|
|
|
import org.junit.jupiter.api.Test; |
|
|
|
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.aop.framework.ProxyFactory; |
|
|
|
import org.springframework.beans.MutablePropertyValues; |
|
|
|
import org.springframework.beans.MutablePropertyValues; |
|
|
|
@ -46,6 +49,7 @@ import org.springframework.scheduling.annotation.AsyncAnnotationBeanPostProcesso |
|
|
|
import org.springframework.util.ClassUtils; |
|
|
|
import org.springframework.util.ClassUtils; |
|
|
|
import org.springframework.util.ReflectionUtils; |
|
|
|
import org.springframework.util.ReflectionUtils; |
|
|
|
import org.springframework.validation.annotation.Validated; |
|
|
|
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.assertThat; |
|
|
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType; |
|
|
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType; |
|
|
|
@ -59,27 +63,39 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
class MethodValidationProxyTests { |
|
|
|
class MethodValidationProxyTests { |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@ParameterizedTest |
|
|
|
|
|
|
|
@ValueSource(booleans = {true, false}) |
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
public void testMethodValidationInterceptor() { |
|
|
|
void testMethodValidationInterceptor(boolean adaptViolations) { |
|
|
|
MyValidBean bean = new MyValidBean(); |
|
|
|
MyValidBean bean = new MyValidBean(); |
|
|
|
ProxyFactory factory = new ProxyFactory(bean); |
|
|
|
ProxyFactory factory = new ProxyFactory(bean); |
|
|
|
factory.addAdvice(new MethodValidationInterceptor()); |
|
|
|
factory.addAdvice(adaptViolations ? |
|
|
|
|
|
|
|
new MethodValidationInterceptor(() -> Validation.buildDefaultValidatorFactory().getValidator(), true) : |
|
|
|
|
|
|
|
new MethodValidationInterceptor()); |
|
|
|
factory.addAdvisor(new AsyncAnnotationAdvisor()); |
|
|
|
factory.addAdvisor(new AsyncAnnotationAdvisor()); |
|
|
|
doTestProxyValidation((MyValidInterface<String>) factory.getProxy()); |
|
|
|
doTestProxyValidation((MyValidInterface<String>) factory.getProxy(), |
|
|
|
|
|
|
|
(adaptViolations ? MethodValidationException.class : ConstraintViolationException.class)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@ParameterizedTest |
|
|
|
|
|
|
|
@ValueSource(booleans = {true, false}) |
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
public void testMethodValidationPostProcessor() { |
|
|
|
void testMethodValidationPostProcessor(boolean adaptViolations) { |
|
|
|
StaticApplicationContext context = new StaticApplicationContext(); |
|
|
|
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(); |
|
|
|
MutablePropertyValues pvs = new MutablePropertyValues(); |
|
|
|
pvs.add("beforeExistingAdvisors", false); |
|
|
|
pvs.add("beforeExistingAdvisors", false); |
|
|
|
context.registerSingleton("aapp", AsyncAnnotationBeanPostProcessor.class, pvs); |
|
|
|
context.registerSingleton("aapp", AsyncAnnotationBeanPostProcessor.class, pvs); |
|
|
|
context.registerSingleton("bean", MyValidBean.class); |
|
|
|
context.registerSingleton("bean", MyValidBean.class); |
|
|
|
context.refresh(); |
|
|
|
context.refresh(); |
|
|
|
doTestProxyValidation(context.getBean("bean", MyValidInterface.class)); |
|
|
|
doTestProxyValidation(context.getBean("bean", MyValidInterface.class), |
|
|
|
|
|
|
|
adaptViolations ? MethodValidationException.class : ConstraintViolationException.class); |
|
|
|
context.close(); |
|
|
|
context.close(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -91,21 +107,21 @@ class MethodValidationProxyTests { |
|
|
|
context.registerBean(MyValidInterface.class, () -> |
|
|
|
context.registerBean(MyValidInterface.class, () -> |
|
|
|
ProxyFactory.getProxy(MyValidInterface.class, new MyValidClientInterfaceMethodInterceptor())); |
|
|
|
ProxyFactory.getProxy(MyValidInterface.class, new MyValidClientInterfaceMethodInterceptor())); |
|
|
|
context.refresh(); |
|
|
|
context.refresh(); |
|
|
|
doTestProxyValidation(context.getBean(MyValidInterface.class)); |
|
|
|
doTestProxyValidation(context.getBean(MyValidInterface.class), ConstraintViolationException.class); |
|
|
|
context.close(); |
|
|
|
context.close(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("DataFlowIssue") |
|
|
|
@SuppressWarnings("DataFlowIssue") |
|
|
|
private void doTestProxyValidation(MyValidInterface<String> proxy) { |
|
|
|
private void doTestProxyValidation(MyValidInterface<String> proxy, Class<? extends Exception> expectedExceptionClass) { |
|
|
|
assertThat(proxy.myValidMethod("value", 5)).isNotNull(); |
|
|
|
assertThat(proxy.myValidMethod("value", 5)).isNotNull(); |
|
|
|
assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> proxy.myValidMethod("value", 15)); |
|
|
|
assertThatExceptionOfType(expectedExceptionClass).isThrownBy(() -> proxy.myValidMethod("value", 15)); |
|
|
|
assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> proxy.myValidMethod(null, 5)); |
|
|
|
assertThatExceptionOfType(expectedExceptionClass).isThrownBy(() -> proxy.myValidMethod(null, 5)); |
|
|
|
assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> proxy.myValidMethod("value", 0)); |
|
|
|
assertThatExceptionOfType(expectedExceptionClass).isThrownBy(() -> proxy.myValidMethod("value", 0)); |
|
|
|
proxy.myValidAsyncMethod("value", 5); |
|
|
|
proxy.myValidAsyncMethod("value", 5); |
|
|
|
assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> proxy.myValidAsyncMethod("value", 15)); |
|
|
|
assertThatExceptionOfType(expectedExceptionClass).isThrownBy(() -> proxy.myValidAsyncMethod("value", 15)); |
|
|
|
assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> proxy.myValidAsyncMethod(null, 5)); |
|
|
|
assertThatExceptionOfType(expectedExceptionClass).isThrownBy(() -> proxy.myValidAsyncMethod(null, 5)); |
|
|
|
assertThat(proxy.myGenericMethod("myValue")).isEqualTo("myValue"); |
|
|
|
assertThat(proxy.myGenericMethod("myValue")).isEqualTo("myValue"); |
|
|
|
assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> proxy.myGenericMethod(null)); |
|
|
|
assertThatExceptionOfType(expectedExceptionClass).isThrownBy(() -> proxy.myGenericMethod(null)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
|