Polishing validation code
See gh-445
This commit is contained in:
@@ -30,8 +30,6 @@ import java.util.concurrent.Executor;
|
|||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.validation.Validator;
|
|
||||||
|
|
||||||
import graphql.schema.DataFetcher;
|
import graphql.schema.DataFetcher;
|
||||||
import graphql.schema.DataFetchingEnvironment;
|
import graphql.schema.DataFetchingEnvironment;
|
||||||
import graphql.schema.FieldCoordinates;
|
import graphql.schema.FieldCoordinates;
|
||||||
@@ -127,7 +125,7 @@ public class AnnotatedControllerConfigurer
|
|||||||
private HandlerMethodArgumentResolverComposite argumentResolvers;
|
private HandlerMethodArgumentResolverComposite argumentResolvers;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private HandlerMethodInputValidator validator;
|
private HandlerMethodValidationHelper validationHelper;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private Consumer<DataBinder> dataBinderInitializer;
|
private Consumer<DataBinder> dataBinderInitializer;
|
||||||
@@ -175,7 +173,8 @@ public class AnnotatedControllerConfigurer
|
|||||||
this.argumentResolvers = initArgumentResolvers();
|
this.argumentResolvers = initArgumentResolvers();
|
||||||
|
|
||||||
if (beanValidationPresent) {
|
if (beanValidationPresent) {
|
||||||
this.validator = HandlerMethodInputValidatorFactory.create(obtainApplicationContext());
|
this.validationHelper =
|
||||||
|
HandlerMethodValidationHelper.createIfValidatorAvailable(obtainApplicationContext());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,7 +228,7 @@ public class AnnotatedControllerConfigurer
|
|||||||
findHandlerMethods().forEach((info) -> {
|
findHandlerMethods().forEach((info) -> {
|
||||||
DataFetcher<?> dataFetcher;
|
DataFetcher<?> dataFetcher;
|
||||||
if (!info.isBatchMapping()) {
|
if (!info.isBatchMapping()) {
|
||||||
dataFetcher = new SchemaMappingDataFetcher(info, this.argumentResolvers, this.validator, this.executor);
|
dataFetcher = new SchemaMappingDataFetcher(info, this.argumentResolvers, this.validationHelper, this.executor);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
String dataLoaderKey = registerBatchLoader(info);
|
String dataLoaderKey = registerBatchLoader(info);
|
||||||
@@ -477,21 +476,21 @@ public class AnnotatedControllerConfigurer
|
|||||||
private final HandlerMethodArgumentResolverComposite argumentResolvers;
|
private final HandlerMethodArgumentResolverComposite argumentResolvers;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private final HandlerMethodInputValidator validator;
|
private final HandlerMethodValidationHelper validatorHelper;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private final Executor executor;
|
private final Executor executor;
|
||||||
|
|
||||||
private final boolean subscription;
|
private final boolean subscription;
|
||||||
|
|
||||||
public SchemaMappingDataFetcher(
|
SchemaMappingDataFetcher(
|
||||||
MappingInfo info, HandlerMethodArgumentResolverComposite resolvers,
|
MappingInfo info, HandlerMethodArgumentResolverComposite resolvers,
|
||||||
@Nullable HandlerMethodInputValidator validator,
|
@Nullable HandlerMethodValidationHelper validatorHelper,
|
||||||
@Nullable Executor executor) {
|
@Nullable Executor executor) {
|
||||||
|
|
||||||
this.info = info;
|
this.info = info;
|
||||||
this.argumentResolvers = resolvers;
|
this.argumentResolvers = resolvers;
|
||||||
this.validator = validator;
|
this.validatorHelper = validatorHelper;
|
||||||
this.executor = executor;
|
this.executor = executor;
|
||||||
this.subscription = this.info.getCoordinates().getTypeName().equalsIgnoreCase("Subscription");
|
this.subscription = this.info.getCoordinates().getTypeName().equalsIgnoreCase("Subscription");
|
||||||
}
|
}
|
||||||
@@ -509,7 +508,7 @@ public class AnnotatedControllerConfigurer
|
|||||||
public Object get(DataFetchingEnvironment environment) throws Exception {
|
public Object get(DataFetchingEnvironment environment) throws Exception {
|
||||||
|
|
||||||
DataFetcherHandlerMethod handlerMethod = new DataFetcherHandlerMethod(
|
DataFetcherHandlerMethod handlerMethod = new DataFetcherHandlerMethod(
|
||||||
getHandlerMethod(), this.argumentResolvers, this.validator, this.executor, this.subscription);
|
getHandlerMethod(), this.argumentResolvers, this.validatorHelper, this.executor, this.subscription);
|
||||||
|
|
||||||
return handlerMethod.invoke(environment);
|
return handlerMethod.invoke(environment);
|
||||||
}
|
}
|
||||||
@@ -520,7 +519,7 @@ public class AnnotatedControllerConfigurer
|
|||||||
|
|
||||||
private final String dataLoaderKey;
|
private final String dataLoaderKey;
|
||||||
|
|
||||||
public BatchMappingDataFetcher(String dataLoaderKey) {
|
BatchMappingDataFetcher(String dataLoaderKey) {
|
||||||
this.dataLoaderKey = dataLoaderKey;
|
this.dataLoaderKey = dataLoaderKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -534,16 +533,4 @@ public class AnnotatedControllerConfigurer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Look for a Validator bean in the context and configure validation support
|
|
||||||
*/
|
|
||||||
static class HandlerMethodInputValidatorFactory {
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
static HandlerMethodInputValidator create(ApplicationContext context) {
|
|
||||||
Validator validator = context.getBeanProvider(Validator.class).getIfAvailable();
|
|
||||||
return validator != null ? new HandlerMethodInputValidator(validator) : null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public class DataFetcherHandlerMethod extends InvocableHandlerMethodSupport {
|
|||||||
private final HandlerMethodArgumentResolverComposite resolvers;
|
private final HandlerMethodArgumentResolverComposite resolvers;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private final HandlerMethodInputValidator validator;
|
private final HandlerMethodValidationHelper validator;
|
||||||
|
|
||||||
private final ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
|
private final ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ public class DataFetcherHandlerMethod extends InvocableHandlerMethodSupport {
|
|||||||
* @param subscription whether the field being fetched is of subscription type
|
* @param subscription whether the field being fetched is of subscription type
|
||||||
*/
|
*/
|
||||||
public DataFetcherHandlerMethod(HandlerMethod handlerMethod,
|
public DataFetcherHandlerMethod(HandlerMethod handlerMethod,
|
||||||
HandlerMethodArgumentResolverComposite resolvers, @Nullable HandlerMethodInputValidator validator,
|
HandlerMethodArgumentResolverComposite resolvers, @Nullable HandlerMethodValidationHelper validator,
|
||||||
@Nullable Executor executor, boolean subscription) {
|
@Nullable Executor executor, boolean subscription) {
|
||||||
|
|
||||||
super(handlerMethod, executor);
|
super(handlerMethod, executor);
|
||||||
@@ -85,12 +85,15 @@ public class DataFetcherHandlerMethod extends InvocableHandlerMethodSupport {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the configured input validator.
|
* Return the configured input validator.
|
||||||
|
* @deprecated as of 1.1 without a replacement
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
@Nullable
|
@Nullable
|
||||||
public HandlerMethodInputValidator getValidator() {
|
public HandlerMethodValidationHelper getValidator() {
|
||||||
return this.validator;
|
return this.validator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoke the method after resolving its argument values in the context of
|
* Invoke the method after resolving its argument values in the context of
|
||||||
* the given {@link DataFetchingEnvironment}.
|
* the given {@link DataFetchingEnvironment}.
|
||||||
|
|||||||
@@ -1,98 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2020-2021 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.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.graphql.data.method.annotation.support;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.validation.ConstraintViolation;
|
|
||||||
import javax.validation.ConstraintViolationException;
|
|
||||||
import javax.validation.Validation;
|
|
||||||
import javax.validation.Validator;
|
|
||||||
|
|
||||||
import org.springframework.core.annotation.AnnotationUtils;
|
|
||||||
import org.springframework.graphql.data.method.HandlerMethod;
|
|
||||||
import org.springframework.graphql.data.method.HandlerMethodArgumentResolver;
|
|
||||||
import org.springframework.util.Assert;
|
|
||||||
import org.springframework.validation.annotation.Validated;
|
|
||||||
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
|
||||||
import org.springframework.validation.beanvalidation.SpringValidatorAdapter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Strategy for validating a {@link HandlerMethod} input before invocation, based on JSR-303.
|
|
||||||
* This is called after all {@link HandlerMethodArgumentResolver} have been involved.
|
|
||||||
*
|
|
||||||
* @author Brian Clozel
|
|
||||||
*/
|
|
||||||
class HandlerMethodInputValidator {
|
|
||||||
|
|
||||||
private final Validator validator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the input validator backed by a JSR-303 Validator instance.
|
|
||||||
*/
|
|
||||||
public HandlerMethodInputValidator(Validator validator) {
|
|
||||||
Assert.notNull(validator, "validator should not be null");
|
|
||||||
if (validator instanceof LocalValidatorFactoryBean) {
|
|
||||||
this.validator = ((LocalValidatorFactoryBean) validator).getValidator();
|
|
||||||
}
|
|
||||||
else if (validator instanceof SpringValidatorAdapter) {
|
|
||||||
this.validator = validator.unwrap(Validator.class);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.validator = validator;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the input validator backed by a default
|
|
||||||
* {@link Validation#buildDefaultValidatorFactory() factory instance}.
|
|
||||||
*/
|
|
||||||
public HandlerMethodInputValidator() {
|
|
||||||
this(Validation.buildDefaultValidatorFactory().getValidator());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate the {@link HandlerMethod} input before invocation, throwing
|
|
||||||
* an {@link ConstraintViolationException} if validation fails.
|
|
||||||
*
|
|
||||||
* @param handlerMethod the handler method for the current request
|
|
||||||
* @param arguments the resolved arguments for the method invocation
|
|
||||||
*/
|
|
||||||
public void validate(HandlerMethod handlerMethod, Object[] arguments) {
|
|
||||||
Class<?>[] validationGroups = determineValidationGroups(handlerMethod);
|
|
||||||
Set<ConstraintViolation<Object>> result = this.validator.forExecutables()
|
|
||||||
.validateParameters(handlerMethod.getBean(), handlerMethod.getMethod(), arguments, validationGroups);
|
|
||||||
if (!result.isEmpty()) {
|
|
||||||
throw new ConstraintViolationException(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine the validation groups to validate against for the given handler method.
|
|
||||||
* <p>Default are the validation groups as specified in the {@link Validated} annotation
|
|
||||||
* on the containing target class of the method.
|
|
||||||
* @param method the current HandlerMethod
|
|
||||||
* @return the applicable validation groups as a Class array
|
|
||||||
*/
|
|
||||||
private Class<?>[] determineValidationGroups(HandlerMethod method) {
|
|
||||||
Validated validatedAnn = AnnotationUtils.findAnnotation(method.getMethod(), Validated.class);
|
|
||||||
if (validatedAnn == null) {
|
|
||||||
validatedAnn = AnnotationUtils.findAnnotation(method.getBeanType(), Validated.class);
|
|
||||||
}
|
|
||||||
return (validatedAnn != null ? validatedAnn.value() : new Class<?>[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020-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.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.graphql.data.method.annotation.support;
|
||||||
|
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.validation.ConstraintViolation;
|
||||||
|
import javax.validation.ConstraintViolationException;
|
||||||
|
import javax.validation.Validator;
|
||||||
|
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.core.annotation.AnnotationUtils;
|
||||||
|
import org.springframework.graphql.data.method.HandlerMethod;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
||||||
|
import org.springframework.validation.beanvalidation.SpringValidatorAdapter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class to apply standard bean validation to a {@link HandlerMethod}.
|
||||||
|
*
|
||||||
|
* @author Brian Clozel
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
final class HandlerMethodValidationHelper {
|
||||||
|
|
||||||
|
private final Validator validator;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor with the {@link Validator} instance to use.
|
||||||
|
*/
|
||||||
|
public HandlerMethodValidationHelper(Validator validator) {
|
||||||
|
Assert.notNull(validator, "validator should not be null");
|
||||||
|
if (validator instanceof LocalValidatorFactoryBean) {
|
||||||
|
this.validator = ((LocalValidatorFactoryBean) validator).getValidator();
|
||||||
|
}
|
||||||
|
else if (validator instanceof SpringValidatorAdapter) {
|
||||||
|
this.validator = validator.unwrap(Validator.class);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.validator = validator;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate the input values to a the {@link HandlerMethod} and throw a
|
||||||
|
* {@link ConstraintViolationException} in case of violations.
|
||||||
|
* @param handlerMethod the handler method to validate
|
||||||
|
* @param arguments the input argument values
|
||||||
|
*/
|
||||||
|
public void validate(HandlerMethod handlerMethod, Object[] arguments) {
|
||||||
|
Set<ConstraintViolation<Object>> result =
|
||||||
|
this.validator.forExecutables().validateParameters(
|
||||||
|
handlerMethod.getBean(), handlerMethod.getMethod(), arguments,
|
||||||
|
determineValidationGroups(handlerMethod));
|
||||||
|
if (!result.isEmpty()) {
|
||||||
|
throw new ConstraintViolationException(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the validation groups to apply to a handler method, specified
|
||||||
|
* through the {@link Validated} annotation on the method or on the class.
|
||||||
|
* @param method the method to check
|
||||||
|
* @return the applicable validation groups as a Class array
|
||||||
|
*/
|
||||||
|
private Class<?>[] determineValidationGroups(HandlerMethod method) {
|
||||||
|
Validated annotation = findAnnotation(method, Validated.class);
|
||||||
|
return (annotation != null ? annotation.value() : new Class<?>[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static <A extends Annotation> A findAnnotation(HandlerMethod method, Class<A> annotationType) {
|
||||||
|
A annotation = AnnotationUtils.findAnnotation(method.getMethod(), annotationType);
|
||||||
|
if (annotation == null) {
|
||||||
|
annotation = AnnotationUtils.findAnnotation(method.getBeanType(), annotationType);
|
||||||
|
}
|
||||||
|
return annotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory method for {@link HandlerMethodValidationHelper} if a
|
||||||
|
* {@link Validator} can be found.
|
||||||
|
* @param context the context to look up a {@code Validator} bean from
|
||||||
|
* @return the helper instance, or {@code null
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public static HandlerMethodValidationHelper createIfValidatorAvailable(ApplicationContext context) {
|
||||||
|
Validator validator = context.getBeanProvider(Validator.class).getIfAvailable();
|
||||||
|
return (validator != null ? new HandlerMethodValidationHelper(validator) : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2020-2021 the original author or authors.
|
* Copyright 2020-2022 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -23,6 +23,7 @@ import java.util.Arrays;
|
|||||||
|
|
||||||
import javax.validation.ConstraintViolation;
|
import javax.validation.ConstraintViolation;
|
||||||
import javax.validation.ConstraintViolationException;
|
import javax.validation.ConstraintViolationException;
|
||||||
|
import javax.validation.Validation;
|
||||||
import javax.validation.constraints.Max;
|
import javax.validation.constraints.Max;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
@@ -39,27 +40,29 @@ import static org.assertj.core.api.Assertions.assertThatNoException;
|
|||||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link HandlerMethodInputValidator}
|
* Unit tests for {@link HandlerMethodValidationHelper}.
|
||||||
* @author Brian Clozel
|
* @author Brian Clozel
|
||||||
*/
|
*/
|
||||||
class HandlerMethodInputValidatorTests {
|
class HandlerMethodValidationHelperTests {
|
||||||
|
|
||||||
|
private final HandlerMethodValidationHelper validator =
|
||||||
|
new HandlerMethodValidationHelper(Validation.buildDefaultValidatorFactory().getValidator());
|
||||||
|
|
||||||
private final HandlerMethodInputValidator validator = new HandlerMethodInputValidator();
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldFailWithNullValidator() {
|
void shouldFailWithNullValidator() {
|
||||||
assertThatThrownBy(() -> new HandlerMethodInputValidator(null)).isInstanceOf(IllegalArgumentException.class);
|
assertThatThrownBy(() -> new HandlerMethodValidationHelper(null)).isInstanceOf(IllegalArgumentException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldIgnoreMethodsWithoutAnnotations() throws Exception {
|
void shouldIgnoreMethodsWithoutAnnotations() {
|
||||||
HandlerMethod method = findHandlerMethod(MyValidBean.class, "notValidatedMethod");
|
HandlerMethod method = findHandlerMethod(MyBean.class, "notValidatedMethod");
|
||||||
assertThatNoException().isThrownBy(() -> validator.validate(method, new Object[] {"test", 12}));
|
assertThatNoException().isThrownBy(() -> validator.validate(method, new Object[] {"test", 12}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldRaiseValidationErrorForAnnotatedParams() throws Exception {
|
void shouldRaiseValidationErrorForAnnotatedParams() {
|
||||||
HandlerMethod method = findHandlerMethod(MyValidBean.class, "myValidMethod");
|
HandlerMethod method = findHandlerMethod(MyBean.class, "myValidMethod");
|
||||||
assertViolations(() -> validator.validate(method, new Object[] {null, 2}))
|
assertViolations(() -> validator.validate(method, new Object[] {null, 2}))
|
||||||
.anyMatch(violation -> violation.getPropertyPath().toString().equals("myValidMethod.arg0"));
|
.anyMatch(violation -> violation.getPropertyPath().toString().equals("myValidMethod.arg0"));
|
||||||
assertViolations(() -> validator.validate(method, new Object[] {"test", 12}))
|
assertViolations(() -> validator.validate(method, new Object[] {"test", 12}))
|
||||||
@@ -67,11 +70,12 @@ class HandlerMethodInputValidatorTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldRaiseValidationErrorForAnnotatedParamsWithGroups() throws Exception {
|
void shouldRaiseValidationErrorForAnnotatedParamsWithGroups() {
|
||||||
HandlerMethod myValidMethodWithGroup = findHandlerMethod(MyValidBeanWithGroup.class, "myValidMethodWithGroup");
|
HandlerMethod myValidMethodWithGroup = findHandlerMethod(MyValidationGroupsBean.class, "myValidMethodWithGroup");
|
||||||
assertViolations(() -> validator.validate(myValidMethodWithGroup, new Object[] {null}))
|
assertViolations(() -> validator.validate(myValidMethodWithGroup, new Object[] {null}))
|
||||||
.anyMatch(violation -> violation.getPropertyPath().toString().equals("myValidMethodWithGroup.arg0"));
|
.anyMatch(violation -> violation.getPropertyPath().toString().equals("myValidMethodWithGroup.arg0"));
|
||||||
HandlerMethod myValidMethodWithGroupOnType = findHandlerMethod(MyValidBeanWithGroup.class, "myValidMethodWithGroupOnType");
|
|
||||||
|
HandlerMethod myValidMethodWithGroupOnType = findHandlerMethod(MyValidationGroupsBean.class, "myValidMethodWithGroupOnType");
|
||||||
assertViolations(() -> validator.validate(myValidMethodWithGroupOnType, new Object[] {null}))
|
assertViolations(() -> validator.validate(myValidMethodWithGroupOnType, new Object[] {null}))
|
||||||
.anyMatch(violation -> violation.getPropertyPath().toString().equals("myValidMethodWithGroupOnType.arg0"));
|
.anyMatch(violation -> violation.getPropertyPath().toString().equals("myValidMethodWithGroupOnType.arg0"));
|
||||||
}
|
}
|
||||||
@@ -93,7 +97,9 @@ class HandlerMethodInputValidatorTests {
|
|||||||
.asInstanceOf(InstanceOfAssertFactories.iterable(ConstraintViolation.class));
|
.asInstanceOf(InstanceOfAssertFactories.iterable(ConstraintViolation.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class MyValidBean {
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private static class MyBean {
|
||||||
|
|
||||||
public String notValidatedMethod(String arg0, int arg1) {
|
public String notValidatedMethod(String arg0, int arg1) {
|
||||||
return "";
|
return "";
|
||||||
@@ -105,27 +111,32 @@ class HandlerMethodInputValidatorTests {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface FirstGroup {
|
|
||||||
|
interface FirstGroup {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public interface SecondGroup {
|
interface SecondGroup {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Validated(FirstGroup.class)
|
@Validated(FirstGroup.class)
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface GroupOnParam {
|
@interface MethodLevelGroup {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Validated(SecondGroup.class)
|
@Validated(SecondGroup.class)
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface GroupOnType {
|
@interface TypeLevelGroup {
|
||||||
}
|
}
|
||||||
|
|
||||||
@GroupOnType
|
|
||||||
public static class MyValidBeanWithGroup {
|
|
||||||
|
|
||||||
@GroupOnParam
|
@TypeLevelGroup
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private static class MyValidationGroupsBean {
|
||||||
|
|
||||||
|
@MethodLevelGroup
|
||||||
public Object myValidMethodWithGroup(@NotNull(groups = {FirstGroup.class}) String arg0) {
|
public Object myValidMethodWithGroup(@NotNull(groups = {FirstGroup.class}) String arg0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user