Add MethodParameter[] input to MethodValidationAdapter
This allows re-use of existing MethodParameter instances from controller methods with cached metadata, and also ensures additional capabilities such as looking up parameter annotations on interfaces. See gh-29825
This commit is contained in:
		
							parent
							
								
									e7c3e1c516
								
							
						
					
					
						commit
						85d81024a4
					
				| 
						 | 
					@ -18,6 +18,7 @@ package org.springframework.validation.beanvalidation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.lang.reflect.Method;
 | 
					import java.lang.reflect.Method;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.springframework.core.MethodParameter;
 | 
				
			||||||
import org.springframework.lang.Nullable;
 | 
					import org.springframework.lang.Nullable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -44,31 +45,45 @@ public class DefaultMethodValidator implements MethodValidator {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Override
 | 
						@Override
 | 
				
			||||||
	public void validateArguments(Object target, Method method, Object[] arguments, Class<?>[] groups) {
 | 
						public void validateArguments(
 | 
				
			||||||
		MethodValidationResult result = this.adapter.validateMethodArguments(target, method, arguments, groups);
 | 
								Object target, Method method, @Nullable MethodParameter[] parameters, Object[] arguments,
 | 
				
			||||||
		handleArgumentsResult(target, method, arguments, groups, result);
 | 
								Class<?>[] groups) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							handleArgumentsValidationResult(target, method, arguments, groups,
 | 
				
			||||||
 | 
									this.adapter.validateMethodArguments(target, method, parameters, arguments, groups));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public void validateReturnValue(
 | 
				
			||||||
 | 
								Object target, Method method, @Nullable MethodParameter returnType, @Nullable Object returnValue,
 | 
				
			||||||
 | 
								Class<?>[] groups) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							handleReturnValueValidationResult(target, method, returnValue, groups,
 | 
				
			||||||
 | 
									this.adapter.validateMethodReturnValue(target, method, returnType, returnValue, groups));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Subclasses can override this to handle the result of argument validation.
 | 
						 * Subclasses can override this to handle the result of argument validation.
 | 
				
			||||||
	 * By default, {@link MethodValidationResult#throwIfViolationsPresent()} is called.
 | 
						 * By default, {@link MethodValidationResult#throwIfViolationsPresent()} is called.
 | 
				
			||||||
 | 
						 * @param bean the target Object for method invocation
 | 
				
			||||||
 | 
						 * @param method the target method
 | 
				
			||||||
 | 
						 * @param arguments the candidate argument values to validate
 | 
				
			||||||
 | 
						 * @param groups groups for validation determined via
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	protected void handleArgumentsResult(
 | 
						protected void handleArgumentsValidationResult(
 | 
				
			||||||
			Object bean, Method method, Object[] arguments, Class<?>[] groups, MethodValidationResult result) {
 | 
								Object bean, Method method, Object[] arguments, Class<?>[] groups, MethodValidationResult result) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		result.throwIfViolationsPresent();
 | 
							result.throwIfViolationsPresent();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public void validateReturnValue(Object target, Method method, @Nullable Object returnValue, Class<?>[] groups) {
 | 
					 | 
				
			||||||
		MethodValidationResult result = this.adapter.validateMethodReturnValue(target, method, returnValue, groups);
 | 
					 | 
				
			||||||
		handleReturnValueResult(target, method, returnValue, groups, result);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Subclasses can override this to handle the result of return value validation.
 | 
						 * Subclasses can override this to handle the result of return value validation.
 | 
				
			||||||
	 * By default, {@link MethodValidationResult#throwIfViolationsPresent()} is called.
 | 
						 * By default, {@link MethodValidationResult#throwIfViolationsPresent()} is called.
 | 
				
			||||||
 | 
						 * @param bean the target Object for method invocation
 | 
				
			||||||
 | 
						 * @param method the target method
 | 
				
			||||||
 | 
						 * @param returnValue the return value to validate
 | 
				
			||||||
 | 
						 * @param groups groups for validation determined via
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	protected void handleReturnValueResult(
 | 
						protected void handleReturnValueValidationResult(
 | 
				
			||||||
			Object bean, Method method, @Nullable Object returnValue, Class<?>[] groups, MethodValidationResult result) {
 | 
								Object bean, Method method, @Nullable Object returnValue, Class<?>[] groups, MethodValidationResult result) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		result.throwIfViolationsPresent();
 | 
							result.throwIfViolationsPresent();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -176,8 +176,8 @@ public class MethodValidationAdapter {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Use this method determine the validation groups to pass into
 | 
						 * Use this method determine the validation groups to pass into
 | 
				
			||||||
	 * {@link #validateMethodArguments(Object, Method, Object[], Class[])} and
 | 
						 * {@link #validateMethodArguments(Object, Method, MethodParameter[], Object[], Class[])} and
 | 
				
			||||||
	 * {@link #validateMethodReturnValue(Object, Method, Object, Class[])}.
 | 
						 * {@link #validateMethodReturnValue(Object, Method, MethodParameter, Object, Class[])}.
 | 
				
			||||||
	 * <p>Default are the validation groups as specified in the {@link Validated}
 | 
						 * <p>Default are the validation groups as specified in the {@link Validated}
 | 
				
			||||||
	 * annotation on the method, or on the containing target class of the method,
 | 
						 * annotation on the method, or on the containing target class of the method,
 | 
				
			||||||
	 * or for an AOP proxy without a target (with all behavior in advisors), also
 | 
						 * or for an AOP proxy without a target (with all behavior in advisors), also
 | 
				
			||||||
| 
						 | 
					@ -208,7 +208,8 @@ public class MethodValidationAdapter {
 | 
				
			||||||
	 * Validate the given method arguments and return the result of validation.
 | 
						 * Validate the given method arguments and return the result of validation.
 | 
				
			||||||
	 * @param target the target Object
 | 
						 * @param target the target Object
 | 
				
			||||||
	 * @param method the target method
 | 
						 * @param method the target method
 | 
				
			||||||
	 * @param arguments candidate arguments for a method invocation
 | 
						 * @param parameters the parameters, if already created and available
 | 
				
			||||||
 | 
						 * @param arguments the candidate argument values to validate
 | 
				
			||||||
	 * @param groups groups for validation determined via
 | 
						 * @param groups groups for validation determined via
 | 
				
			||||||
	 * {@link #determineValidationGroups(Object, Method)}
 | 
						 * {@link #determineValidationGroups(Object, Method)}
 | 
				
			||||||
	 * @return a result with {@link ConstraintViolation violations} and
 | 
						 * @return a result with {@link ConstraintViolation violations} and
 | 
				
			||||||
| 
						 | 
					@ -216,7 +217,8 @@ public class MethodValidationAdapter {
 | 
				
			||||||
	 * in case there are no violations
 | 
						 * in case there are no violations
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public MethodValidationResult validateMethodArguments(
 | 
						public MethodValidationResult validateMethodArguments(
 | 
				
			||||||
			Object target, Method method, Object[] arguments, Class<?>[] groups) {
 | 
								Object target, Method method, @Nullable MethodParameter[] parameters, Object[] arguments,
 | 
				
			||||||
 | 
								Class<?>[] groups) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ExecutableValidator execVal = this.validator.get().forExecutables();
 | 
							ExecutableValidator execVal = this.validator.get().forExecutables();
 | 
				
			||||||
		Set<ConstraintViolation<Object>> result;
 | 
							Set<ConstraintViolation<Object>> result;
 | 
				
			||||||
| 
						 | 
					@ -231,14 +233,18 @@ public class MethodValidationAdapter {
 | 
				
			||||||
			result = execVal.validateParameters(target, bridgedMethod, arguments, groups);
 | 
								result = execVal.validateParameters(target, bridgedMethod, arguments, groups);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return (result.isEmpty() ? EMPTY_RESULT :
 | 
							return (result.isEmpty() ? EMPTY_RESULT :
 | 
				
			||||||
				createException(target, method, result, i -> arguments[i], false));
 | 
									createException(target, method, result,
 | 
				
			||||||
 | 
											i -> parameters != null ? parameters[i] : new MethodParameter(method, i),
 | 
				
			||||||
 | 
											i -> arguments[i],
 | 
				
			||||||
 | 
											false));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Validate the given return value and return the result of validation.
 | 
						 * Validate the given return value and return the result of validation.
 | 
				
			||||||
	 * @param target the target Object
 | 
						 * @param target the target Object
 | 
				
			||||||
	 * @param method the target method
 | 
						 * @param method the target method
 | 
				
			||||||
	 * @param returnValue value returned from invoking the target method
 | 
						 * @param returnType the return parameter, if already created and available
 | 
				
			||||||
 | 
						 * @param returnValue the return value to validate
 | 
				
			||||||
	 * @param groups groups for validation determined via
 | 
						 * @param groups groups for validation determined via
 | 
				
			||||||
	 * {@link #determineValidationGroups(Object, Method)}
 | 
						 * {@link #determineValidationGroups(Object, Method)}
 | 
				
			||||||
	 * @return a result with {@link ConstraintViolation violations} and
 | 
						 * @return a result with {@link ConstraintViolation violations} and
 | 
				
			||||||
| 
						 | 
					@ -246,16 +252,22 @@ public class MethodValidationAdapter {
 | 
				
			||||||
	 * in case there are no violations
 | 
						 * in case there are no violations
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public MethodValidationResult validateMethodReturnValue(
 | 
						public MethodValidationResult validateMethodReturnValue(
 | 
				
			||||||
			Object target, Method method, @Nullable Object returnValue, Class<?>[] groups) {
 | 
								Object target, Method method, @Nullable MethodParameter returnType, @Nullable Object returnValue,
 | 
				
			||||||
 | 
								Class<?>[] groups) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ExecutableValidator execVal = this.validator.get().forExecutables();
 | 
							ExecutableValidator execVal = this.validator.get().forExecutables();
 | 
				
			||||||
		Set<ConstraintViolation<Object>> result = execVal.validateReturnValue(target, method, returnValue, groups);
 | 
							Set<ConstraintViolation<Object>> result = execVal.validateReturnValue(target, method, returnValue, groups);
 | 
				
			||||||
		return (result.isEmpty() ? EMPTY_RESULT : createException(target, method, result, i -> returnValue, true));
 | 
							return (result.isEmpty() ? EMPTY_RESULT :
 | 
				
			||||||
 | 
									createException(target, method, result,
 | 
				
			||||||
 | 
											i -> returnType != null ? returnType : new MethodParameter(method, -1),
 | 
				
			||||||
 | 
											i -> returnValue,
 | 
				
			||||||
 | 
											true));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private MethodValidationException createException(
 | 
						private MethodValidationException createException(
 | 
				
			||||||
			Object target, Method method, Set<ConstraintViolation<Object>> violations,
 | 
								Object target, Method method, Set<ConstraintViolation<Object>> violations,
 | 
				
			||||||
			Function<Integer, Object> argumentFunction, boolean forReturnValue) {
 | 
								Function<Integer, MethodParameter> parameterFunction, Function<Integer, Object> argumentFunction,
 | 
				
			||||||
 | 
								boolean forReturnValue) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Map<MethodParameter, ValueResultBuilder> parameterViolations = new LinkedHashMap<>();
 | 
							Map<MethodParameter, ValueResultBuilder> parameterViolations = new LinkedHashMap<>();
 | 
				
			||||||
		Map<Path.Node, BeanResultBuilder> cascadedViolations = new LinkedHashMap<>();
 | 
							Map<Path.Node, BeanResultBuilder> cascadedViolations = new LinkedHashMap<>();
 | 
				
			||||||
| 
						 | 
					@ -267,10 +279,11 @@ public class MethodValidationAdapter {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				MethodParameter parameter;
 | 
									MethodParameter parameter;
 | 
				
			||||||
				if (node.getKind().equals(ElementKind.PARAMETER)) {
 | 
									if (node.getKind().equals(ElementKind.PARAMETER)) {
 | 
				
			||||||
					parameter = new MethodParameter(method, node.as(Path.ParameterNode.class).getParameterIndex());
 | 
										int index = node.as(Path.ParameterNode.class).getParameterIndex();
 | 
				
			||||||
 | 
										parameter = parameterFunction.apply(index);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				else if (node.getKind().equals(ElementKind.RETURN_VALUE)) {
 | 
									else if (node.getKind().equals(ElementKind.RETURN_VALUE)) {
 | 
				
			||||||
					parameter = new MethodParameter(method, -1);
 | 
										parameter = parameterFunction.apply(-1);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				else {
 | 
									else {
 | 
				
			||||||
					continue;
 | 
										continue;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -104,12 +104,12 @@ public class MethodValidationInterceptor implements MethodInterceptor {
 | 
				
			||||||
		Method method = invocation.getMethod();
 | 
							Method method = invocation.getMethod();
 | 
				
			||||||
		Class<?>[] groups = determineValidationGroups(invocation);
 | 
							Class<?>[] groups = determineValidationGroups(invocation);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		this.delegate.validateMethodArguments(target, method, invocation.getArguments(), groups)
 | 
							this.delegate.validateMethodArguments(target, method, null, invocation.getArguments(), groups)
 | 
				
			||||||
				.throwIfViolationsPresent();
 | 
									.throwIfViolationsPresent();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Object returnValue = invocation.proceed();
 | 
							Object returnValue = invocation.proceed();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		this.delegate.validateMethodReturnValue(target, method, returnValue, groups)
 | 
							this.delegate.validateMethodReturnValue(target, method, null, returnValue, groups)
 | 
				
			||||||
				.throwIfViolationsPresent();
 | 
									.throwIfViolationsPresent();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return returnValue;
 | 
							return returnValue;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,6 +18,7 @@ package org.springframework.validation.beanvalidation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.lang.reflect.Method;
 | 
					import java.lang.reflect.Method;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.springframework.core.MethodParameter;
 | 
				
			||||||
import org.springframework.lang.Nullable;
 | 
					import org.springframework.lang.Nullable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -35,8 +36,8 @@ public interface MethodValidator {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Use this method determine the validation groups to pass into
 | 
						 * Use this method determine the validation groups to pass into
 | 
				
			||||||
	 * {@link #validateArguments(Object, Method, Object[], Class[])} and
 | 
						 * {@link #validateArguments(Object, Method, MethodParameter[], Object[], Class[])} and
 | 
				
			||||||
	 * {@link #validateReturnValue(Object, Method, Object, Class[])}.
 | 
						 * {@link #validateReturnValue(Object, Method, MethodParameter, Object, Class[])}.
 | 
				
			||||||
	 * @param target the target Object
 | 
						 * @param target the target Object
 | 
				
			||||||
	 * @param method the target method
 | 
						 * @param method the target method
 | 
				
			||||||
	 * @return the applicable validation groups as a {@code Class} array
 | 
						 * @return the applicable validation groups as a {@code Class} array
 | 
				
			||||||
| 
						 | 
					@ -48,24 +49,30 @@ public interface MethodValidator {
 | 
				
			||||||
	 * Validate the given method arguments and return the result of validation.
 | 
						 * Validate the given method arguments and return the result of validation.
 | 
				
			||||||
	 * @param target the target Object
 | 
						 * @param target the target Object
 | 
				
			||||||
	 * @param method the target method
 | 
						 * @param method the target method
 | 
				
			||||||
	 * @param arguments candidate arguments for a method invocation
 | 
						 * @param parameters the parameters, if already created and available
 | 
				
			||||||
 | 
						 * @param arguments the candidate argument values to validate
 | 
				
			||||||
	 * @param groups groups for validation determined via
 | 
						 * @param groups groups for validation determined via
 | 
				
			||||||
	 * {@link #determineValidationGroups(Object, Method)}
 | 
						 * {@link #determineValidationGroups(Object, Method)}
 | 
				
			||||||
	 * @throws MethodValidationException should be raised in case of validation
 | 
						 * @throws MethodValidationException should be raised in case of validation
 | 
				
			||||||
	 * errors unless the implementation handles those errors otherwise (e.g.
 | 
						 * errors unless the implementation handles those errors otherwise (e.g.
 | 
				
			||||||
	 * by injecting {@code BindingResult} into the method).
 | 
						 * by injecting {@code BindingResult} into the method).
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	void validateArguments(Object target, Method method, Object[] arguments, Class<?>[] groups);
 | 
						void validateArguments(
 | 
				
			||||||
 | 
								Object target, Method method, @Nullable MethodParameter[] parameters, Object[] arguments,
 | 
				
			||||||
 | 
								Class<?>[] groups);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Validate the given return value and return the result of validation.
 | 
						 * Validate the given return value and return the result of validation.
 | 
				
			||||||
	 * @param target the target Object
 | 
						 * @param target the target Object
 | 
				
			||||||
	 * @param method the target method
 | 
						 * @param method the target method
 | 
				
			||||||
	 * @param returnValue value returned from invoking the target method
 | 
						 * @param returnType the return parameter, if already created and available
 | 
				
			||||||
 | 
						 * @param returnValue the return value to validate
 | 
				
			||||||
	 * @param groups groups for validation determined via
 | 
						 * @param groups groups for validation determined via
 | 
				
			||||||
	 * {@link #determineValidationGroups(Object, Method)}
 | 
						 * {@link #determineValidationGroups(Object, Method)}
 | 
				
			||||||
	 * @throws MethodValidationException in case of validation errors
 | 
						 * @throws MethodValidationException in case of validation errors
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	void validateReturnValue(Object target, Method method, @Nullable Object returnValue, Class<?>[] groups);
 | 
						void validateReturnValue(
 | 
				
			||||||
 | 
								Object target, Method method, @Nullable MethodParameter returnType, @Nullable Object returnValue,
 | 
				
			||||||
 | 
								Class<?>[] groups);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -181,14 +181,14 @@ public class MethodValidationAdapterTests {
 | 
				
			||||||
			Object target, Method method, Object[] arguments, Consumer<MethodValidationResult> assertions) {
 | 
								Object target, Method method, Object[] arguments, Consumer<MethodValidationResult> assertions) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		assertions.accept(
 | 
							assertions.accept(
 | 
				
			||||||
				this.validationAdapter.validateMethodArguments(target, method, arguments, new Class<?>[0]));
 | 
									this.validationAdapter.validateMethodArguments(target, method, null, arguments, new Class<?>[0]));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private void validateReturnValue(
 | 
						private void validateReturnValue(
 | 
				
			||||||
			Object target, Method method, @Nullable Object returnValue, Consumer<MethodValidationResult> assertions) {
 | 
								Object target, Method method, @Nullable Object returnValue, Consumer<MethodValidationResult> assertions) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		assertions.accept(
 | 
							assertions.accept(
 | 
				
			||||||
				this.validationAdapter.validateMethodReturnValue(target, method, returnValue, new Class<?>[0]));
 | 
									this.validationAdapter.validateMethodReturnValue(target, method, null, returnValue, new Class<?>[0]));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private static void assertBeanResult(
 | 
						private static void assertBeanResult(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -46,28 +46,16 @@ import org.springframework.web.method.annotation.ModelFactory;
 | 
				
			||||||
 * @author Rossen Stoyanchev
 | 
					 * @author Rossen Stoyanchev
 | 
				
			||||||
 * @since 6.1
 | 
					 * @since 6.1
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public class HandlerMethodValidator extends DefaultMethodValidator {
 | 
					public final class HandlerMethodValidator extends DefaultMethodValidator {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public HandlerMethodValidator(MethodValidationAdapter adapter) {
 | 
						private HandlerMethodValidator(MethodValidationAdapter adapter) {
 | 
				
			||||||
		super(adapter);
 | 
							super(adapter);
 | 
				
			||||||
		adapter.setBindingResultNameResolver(this::determineObjectName);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private String determineObjectName(MethodParameter param, @Nullable Object argument) {
 | 
					 | 
				
			||||||
		if (param.hasParameterAnnotation(RequestBody.class) || param.hasParameterAnnotation(RequestPart.class)) {
 | 
					 | 
				
			||||||
			return Conventions.getVariableNameForParameter(param);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		else {
 | 
					 | 
				
			||||||
			return ((param.getParameterIndex() != -1) ?
 | 
					 | 
				
			||||||
					ModelFactory.getNameForParameter(param) :
 | 
					 | 
				
			||||||
					ModelFactory.getNameForReturnValue(argument, param));
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Override
 | 
						@Override
 | 
				
			||||||
	protected void handleArgumentsResult(
 | 
						protected void handleArgumentsValidationResult(
 | 
				
			||||||
			Object bean, Method method, Object[] arguments, Class<?>[] groups, MethodValidationResult result) {
 | 
								Object bean, Method method, Object[] arguments, Class<?>[] groups, MethodValidationResult result) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (result.getConstraintViolations().isEmpty()) {
 | 
							if (result.getConstraintViolations().isEmpty()) {
 | 
				
			||||||
| 
						 | 
					@ -93,12 +81,21 @@ public class HandlerMethodValidator extends DefaultMethodValidator {
 | 
				
			||||||
		result.throwIfViolationsPresent();
 | 
							result.throwIfViolationsPresent();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private String determineObjectName(MethodParameter param, @Nullable Object argument) {
 | 
				
			||||||
 | 
							if (param.hasParameterAnnotation(RequestBody.class) || param.hasParameterAnnotation(RequestPart.class)) {
 | 
				
			||||||
 | 
								return Conventions.getVariableNameForParameter(param);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else {
 | 
				
			||||||
 | 
								return ((param.getParameterIndex() != -1) ?
 | 
				
			||||||
 | 
										ModelFactory.getNameForParameter(param) :
 | 
				
			||||||
 | 
										ModelFactory.getNameForReturnValue(argument, param));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Create a {@link MethodValidator} if Bean Validation is enabled in Spring MVC or WebFlux.
 | 
						 * Static factory method to create a {@link HandlerMethodValidator} if Bean
 | 
				
			||||||
	 * @param bindingInitializer for the configured Validator and MessageCodesResolver
 | 
						 * Validation is enabled in Spring MVC or WebFlux.
 | 
				
			||||||
	 * @param parameterNameDiscoverer the {@code ParameterNameDiscoverer} to use
 | 
					 | 
				
			||||||
	 * for {@link MethodValidationAdapter#setParameterNameDiscoverer}
 | 
					 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	@Nullable
 | 
						@Nullable
 | 
				
			||||||
	public static MethodValidator from(
 | 
						public static MethodValidator from(
 | 
				
			||||||
| 
						 | 
					@ -107,15 +104,17 @@ public class HandlerMethodValidator extends DefaultMethodValidator {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (bindingInitializer instanceof ConfigurableWebBindingInitializer configurableInitializer) {
 | 
							if (bindingInitializer instanceof ConfigurableWebBindingInitializer configurableInitializer) {
 | 
				
			||||||
			if (configurableInitializer.getValidator() instanceof Validator validator) {
 | 
								if (configurableInitializer.getValidator() instanceof Validator validator) {
 | 
				
			||||||
				MethodValidationAdapter validationAdapter = new MethodValidationAdapter(validator);
 | 
									MethodValidationAdapter adapter = new MethodValidationAdapter(validator);
 | 
				
			||||||
				if (parameterNameDiscoverer != null) {
 | 
									if (parameterNameDiscoverer != null) {
 | 
				
			||||||
					validationAdapter.setParameterNameDiscoverer(parameterNameDiscoverer);
 | 
										adapter.setParameterNameDiscoverer(parameterNameDiscoverer);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				MessageCodesResolver codesResolver = configurableInitializer.getMessageCodesResolver();
 | 
									MessageCodesResolver codesResolver = configurableInitializer.getMessageCodesResolver();
 | 
				
			||||||
				if (codesResolver != null) {
 | 
									if (codesResolver != null) {
 | 
				
			||||||
					validationAdapter.setMessageCodesResolver(codesResolver);
 | 
										adapter.setMessageCodesResolver(codesResolver);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				return new HandlerMethodValidator(validationAdapter);
 | 
									HandlerMethodValidator methodValidator = new HandlerMethodValidator(adapter);
 | 
				
			||||||
 | 
									adapter.setBindingResultNameResolver(methodValidator::determineObjectName);
 | 
				
			||||||
 | 
									return methodValidator;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return null;
 | 
							return null;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -168,13 +168,15 @@ public class InvocableHandlerMethod extends HandlerMethod {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Class<?>[] groups = getValidationGroups();
 | 
							Class<?>[] groups = getValidationGroups();
 | 
				
			||||||
		if (shouldValidateArguments() && this.methodValidator != null) {
 | 
							if (shouldValidateArguments() && this.methodValidator != null) {
 | 
				
			||||||
			this.methodValidator.validateArguments(getBean(), getBridgedMethod(), args, groups);
 | 
								this.methodValidator.validateArguments(
 | 
				
			||||||
 | 
										getBean(), getBridgedMethod(), getMethodParameters(), args, groups);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Object returnValue = doInvoke(args);
 | 
							Object returnValue = doInvoke(args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (shouldValidateReturnValue() && this.methodValidator != null) {
 | 
							if (shouldValidateReturnValue() && this.methodValidator != null) {
 | 
				
			||||||
			this.methodValidator.validateReturnValue(getBean(), getBridgedMethod(), returnValue, groups);
 | 
								this.methodValidator.validateReturnValue(
 | 
				
			||||||
 | 
										getBean(), getBridgedMethod(), getReturnType(), returnValue, groups);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return returnValue;
 | 
							return returnValue;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -152,7 +152,8 @@ public class InvocableHandlerMethod extends HandlerMethod {
 | 
				
			||||||
		return getMethodArgumentValues(exchange, bindingContext, providedArgs).flatMap(args -> {
 | 
							return getMethodArgumentValues(exchange, bindingContext, providedArgs).flatMap(args -> {
 | 
				
			||||||
			Class<?>[] groups = getValidationGroups();
 | 
								Class<?>[] groups = getValidationGroups();
 | 
				
			||||||
			if (shouldValidateArguments() && this.methodValidator != null) {
 | 
								if (shouldValidateArguments() && this.methodValidator != null) {
 | 
				
			||||||
				this.methodValidator.validateArguments(getBean(), getBridgedMethod(), args, groups);
 | 
									this.methodValidator.validateArguments(
 | 
				
			||||||
 | 
											getBean(), getBridgedMethod(), getMethodParameters(), args, groups);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			Object value;
 | 
								Object value;
 | 
				
			||||||
			Method method = getBridgedMethod();
 | 
								Method method = getBridgedMethod();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue