@@ -176,8 +176,8 @@ public void setBindingResultNameResolver(BindingResultNameResolver nameResolver)
176
176
177
177
/**
178
178
* Use this method determine the validation groups to pass into
179
- * {@link #validateMethodArguments(Object, Method, Object[], Class[])} and
180
- * {@link #validateMethodReturnValue(Object, Method, Object, Class[])}.
179
+ * {@link #validateMethodArguments(Object, Method, MethodParameter[], Object[], Class[])} and
180
+ * {@link #validateMethodReturnValue(Object, Method, MethodParameter, Object, Class[])}.
181
181
* <p>Default are the validation groups as specified in the {@link Validated}
182
182
* annotation on the method, or on the containing target class of the method,
183
183
* or for an AOP proxy without a target (with all behavior in advisors), also
@@ -208,15 +208,17 @@ public static Class<?>[] determineValidationGroups(Object target, Method method)
208
208
* Validate the given method arguments and return the result of validation.
209
209
* @param target the target Object
210
210
* @param method the target method
211
- * @param arguments candidate arguments for a method invocation
211
+ * @param parameters the parameters, if already created and available
212
+ * @param arguments the candidate argument values to validate
212
213
* @param groups groups for validation determined via
213
214
* {@link #determineValidationGroups(Object, Method)}
214
215
* @return a result with {@link ConstraintViolation violations} and
215
216
* {@link ParameterValidationResult validationResults}, both possibly empty
216
217
* in case there are no violations
217
218
*/
218
219
public MethodValidationResult validateMethodArguments (
219
- Object target , Method method , Object [] arguments , Class <?>[] groups ) {
220
+ Object target , Method method , @ Nullable MethodParameter [] parameters , Object [] arguments ,
221
+ Class <?>[] groups ) {
220
222
221
223
ExecutableValidator execVal = this .validator .get ().forExecutables ();
222
224
Set <ConstraintViolation <Object >> result ;
@@ -231,31 +233,41 @@ public MethodValidationResult validateMethodArguments(
231
233
result = execVal .validateParameters (target , bridgedMethod , arguments , groups );
232
234
}
233
235
return (result .isEmpty () ? EMPTY_RESULT :
234
- createException (target , method , result , i -> arguments [i ], false ));
236
+ createException (target , method , result ,
237
+ i -> parameters != null ? parameters [i ] : new MethodParameter (method , i ),
238
+ i -> arguments [i ],
239
+ false ));
235
240
}
236
241
237
242
/**
238
243
* Validate the given return value and return the result of validation.
239
244
* @param target the target Object
240
245
* @param method the target method
241
- * @param returnValue value returned from invoking the target method
246
+ * @param returnType the return parameter, if already created and available
247
+ * @param returnValue the return value to validate
242
248
* @param groups groups for validation determined via
243
249
* {@link #determineValidationGroups(Object, Method)}
244
250
* @return a result with {@link ConstraintViolation violations} and
245
251
* {@link ParameterValidationResult validationResults}, both possibly empty
246
252
* in case there are no violations
247
253
*/
248
254
public MethodValidationResult validateMethodReturnValue (
249
- Object target , Method method , @ Nullable Object returnValue , Class <?>[] groups ) {
255
+ Object target , Method method , @ Nullable MethodParameter returnType , @ Nullable Object returnValue ,
256
+ Class <?>[] groups ) {
250
257
251
258
ExecutableValidator execVal = this .validator .get ().forExecutables ();
252
259
Set <ConstraintViolation <Object >> result = execVal .validateReturnValue (target , method , returnValue , groups );
253
- return (result .isEmpty () ? EMPTY_RESULT : createException (target , method , result , i -> returnValue , true ));
260
+ return (result .isEmpty () ? EMPTY_RESULT :
261
+ createException (target , method , result ,
262
+ i -> returnType != null ? returnType : new MethodParameter (method , -1 ),
263
+ i -> returnValue ,
264
+ true ));
254
265
}
255
266
256
267
private MethodValidationException createException (
257
268
Object target , Method method , Set <ConstraintViolation <Object >> violations ,
258
- Function <Integer , Object > argumentFunction , boolean forReturnValue ) {
269
+ Function <Integer , MethodParameter > parameterFunction , Function <Integer , Object > argumentFunction ,
270
+ boolean forReturnValue ) {
259
271
260
272
Map <MethodParameter , ValueResultBuilder > parameterViolations = new LinkedHashMap <>();
261
273
Map <Path .Node , BeanResultBuilder > cascadedViolations = new LinkedHashMap <>();
@@ -267,10 +279,11 @@ private MethodValidationException createException(
267
279
268
280
MethodParameter parameter ;
269
281
if (node .getKind ().equals (ElementKind .PARAMETER )) {
270
- parameter = new MethodParameter (method , node .as (Path .ParameterNode .class ).getParameterIndex ());
282
+ int index = node .as (Path .ParameterNode .class ).getParameterIndex ();
283
+ parameter = parameterFunction .apply (index );
271
284
}
272
285
else if (node .getKind ().equals (ElementKind .RETURN_VALUE )) {
273
- parameter = new MethodParameter ( method , -1 );
286
+ parameter = parameterFunction . apply ( -1 );
274
287
}
275
288
else {
276
289
continue ;
0 commit comments