Revised validation javadoc, plus protected validate/isBindingErrorFatal template methods

Issue: SPR-12655
This commit is contained in:
Juergen Hoeller 2015-02-10 19:28:30 +01:00
parent 981aefc2c0
commit 7585be85f3
5 changed files with 60 additions and 37 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2015 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.
@ -144,6 +144,16 @@ public class PayloadArgumentResolver implements HandlerMethodArgumentResolver {
}
}
/**
* Validate the payload if applicable.
* <p>The default implementation checks for {@code @javax.validation.Valid},
* Spring's {@link org.springframework.validation.annotation.Validated},
* and custom annotations whose name starts with "Valid".
* @param message the currently processed message
* @param parameter the method parameter
* @param target the target payload object
* @throws MethodArgumentNotValidException in case of binding errors
*/
protected void validate(Message<?> message, MethodParameter parameter, Object target) {
if (this.validator == null) {
return;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2015 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.
@ -56,7 +56,7 @@ import org.springframework.web.method.support.ModelAndViewContainer;
*/
public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResolver, HandlerMethodReturnValueHandler {
protected Log logger = LogFactory.getLog(this.getClass());
protected final Log logger = LogFactory.getLog(getClass());
private final boolean annotationNotRequired;
@ -72,8 +72,8 @@ public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResol
/**
* @return true if the parameter is annotated with {@link ModelAttribute}
* or in default resolution mode also if it is not a simple type.
* Returns {@code true} if the parameter is annotated with {@link ModelAttribute}
* or in default resolution mode, and also if it is not a simple type.
*/
@Override
public boolean supportsParameter(MethodParameter parameter) {
@ -151,7 +151,9 @@ public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResol
/**
* Validate the model attribute if applicable.
* <p>The default implementation checks for {@code @javax.validation.Valid}.
* <p>The default implementation checks for {@code @javax.validation.Valid},
* Spring's {@link org.springframework.validation.annotation.Validated},
* and custom annotations whose name starts with "Valid".
* @param binder the DataBinder to be used
* @param parameter the method parameter
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2015 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.
@ -37,6 +37,7 @@ import org.springframework.http.converter.GenericHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.util.Assert;
import org.springframework.validation.Errors;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
@ -79,6 +80,7 @@ public abstract class AbstractMessageConverterMethodArgumentResolver implements
return Collections.unmodifiableList(result);
}
/**
* Create the method argument value of the expected parameter type by
* reading from the given request.
@ -162,4 +164,17 @@ public abstract class AbstractMessageConverterMethodArgumentResolver implements
return new ServletServerHttpRequest(servletRequest);
}
/**
* Whether to raise a handler method invocation exception on validation errors.
* @param parameter the method argument
* @return {@code true} if the next method argument is not of type {@link Errors}
* @since 4.1.5
*/
protected boolean isBindingErrorFatal(MethodParameter parameter) {
int i = parameter.getParameterIndex();
Class<?>[] paramTypes = parameter.getMethod().getParameterTypes();
boolean hasBindingResult = (paramTypes.length > (i + 1) && Errors.class.isAssignableFrom(paramTypes[i + 1]));
return !hasBindingResult;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2015 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.
@ -222,7 +222,18 @@ public class RequestPartMethodArgumentResolver extends AbstractMessageConverterM
return null;
}
private void validate(WebDataBinder binder, MethodParameter parameter) throws MethodArgumentNotValidException {
/**
* Validate the request part if applicable.
* <p>The default implementation checks for {@code @javax.validation.Valid},
* Spring's {@link org.springframework.validation.annotation.Validated},
* and custom annotations whose name starts with "Valid".
* @param binder the DataBinder to be used
* @param parameter the method parameter
* @throws MethodArgumentNotValidException in case of a binding error which
* is meant to be fatal (i.e. without a declared {@link Errors} parameter)
* @see #isBindingErrorFatal
*/
protected void validate(WebDataBinder binder, MethodParameter parameter) throws MethodArgumentNotValidException {
Annotation[] annotations = parameter.getParameterAnnotations();
for (Annotation ann : annotations) {
Validated validatedAnn = AnnotationUtils.getAnnotation(ann, Validated.class);
@ -240,18 +251,6 @@ public class RequestPartMethodArgumentResolver extends AbstractMessageConverterM
}
}
/**
* Whether to raise a {@link MethodArgumentNotValidException} on validation errors.
* @param parameter the method argument
* @return {@code true} if the next method argument is not of type {@link Errors}
*/
private boolean isBindingErrorFatal(MethodParameter parameter) {
int i = parameter.getParameterIndex();
Class<?>[] paramTypes = parameter.getMethod().getParameterTypes();
boolean hasBindingResult = (paramTypes.length > (i + 1) && Errors.class.isAssignableFrom(paramTypes[i + 1]));
return !hasBindingResult;
}
/**
* Inner class to avoid hard-coded dependency on Servlet 3.0 Part type...

View File

@ -112,7 +112,18 @@ public class RequestResponseBodyMethodProcessor extends AbstractMessageConverter
return argument;
}
private void validate(WebDataBinder binder, MethodParameter parameter) throws Exception {
/**
* Validate the request part if applicable.
* <p>The default implementation checks for {@code @javax.validation.Valid},
* Spring's {@link org.springframework.validation.annotation.Validated},
* and custom annotations whose name starts with "Valid".
* @param binder the DataBinder to be used
* @param parameter the method parameter
* @throws MethodArgumentNotValidException in case of a binding error which
* is meant to be fatal (i.e. without a declared {@link Errors} parameter)
* @see #isBindingErrorFatal
*/
protected void validate(WebDataBinder binder, MethodParameter parameter) throws MethodArgumentNotValidException {
Annotation[] annotations = parameter.getParameterAnnotations();
for (Annotation ann : annotations) {
Validated validatedAnn = AnnotationUtils.getAnnotation(ann, Validated.class);
@ -122,7 +133,7 @@ public class RequestResponseBodyMethodProcessor extends AbstractMessageConverter
binder.validate(validationHints);
BindingResult bindingResult = binder.getBindingResult();
if (bindingResult.hasErrors()) {
if (isBindExceptionRequired(binder, parameter)) {
if (isBindingErrorFatal(parameter)) {
throw new MethodArgumentNotValidException(parameter, bindingResult);
}
}
@ -131,20 +142,6 @@ public class RequestResponseBodyMethodProcessor extends AbstractMessageConverter
}
}
/**
* Whether to raise a {@link MethodArgumentNotValidException} on validation errors.
* @param binder the data binder used to perform data binding
* @param parameter the method argument
* @return {@code true} if the next method argument is not of type {@link Errors}.
*/
private boolean isBindExceptionRequired(WebDataBinder binder, MethodParameter parameter) {
int i = parameter.getParameterIndex();
Class<?>[] paramTypes = parameter.getMethod().getParameterTypes();
boolean hasBindingResult = (paramTypes.length > (i + 1) && Errors.class.isAssignableFrom(paramTypes[i + 1]));
return !hasBindingResult;
}
@Override
protected <T> Object readWithMessageConverters(NativeWebRequest webRequest,
MethodParameter methodParam, Type paramType) throws IOException, HttpMediaTypeNotSupportedException {