public class ModelAttributeMethodProcessor extends Object implements HandlerMethodArgumentResolver, HandlerMethodReturnValueHandler
@ModelAttribute annotated method arguments and handle
return values from @ModelAttribute annotated methods.
Model attributes are obtained from the model or created with a default
constructor (and then added to the model). Once created the attribute is
populated via data binding to Servlet request parameters. Validation may be
applied if the argument is annotated with @javax.validation.Valid.
or Spring's own @org.springframework.validation.annotation.Validated.
When this handler is created with annotationNotRequired=true
any non-simple type argument and return value is regarded as a model
attribute with or without the presence of an @ModelAttribute.
| Constructor and Description |
|---|
ModelAttributeMethodProcessor(boolean annotationNotRequired)
Class constructor.
|
| Modifier and Type | Method and Description |
|---|---|
protected void |
bindRequestParameters(WebDataBinder binder,
NativeWebRequest request)
Extension point to bind the request to the target object.
|
protected Object |
constructAttribute(Constructor<?> ctor,
String attributeName,
MethodParameter parameter,
WebDataBinderFactory binderFactory,
NativeWebRequest webRequest)
Construct a new attribute instance with the given constructor.
|
protected Object |
createAttribute(String attributeName,
MethodParameter parameter,
WebDataBinderFactory binderFactory,
NativeWebRequest webRequest)
Extension point to create the model attribute if not found in the model,
with subsequent parameter binding through bean properties (unless suppressed).
|
void |
handleReturnValue(Object returnValue,
MethodParameter returnType,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest)
Add non-null return values to the
ModelAndViewContainer. |
protected boolean |
isBindExceptionRequired(MethodParameter parameter)
Whether to raise a fatal bind exception on validation errors.
|
protected boolean |
isBindExceptionRequired(WebDataBinder binder,
MethodParameter parameter)
Whether to raise a fatal bind exception on validation errors.
|
Object |
resolveArgument(MethodParameter parameter,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
WebDataBinderFactory binderFactory)
Resolve the argument from the model or if not found instantiate it with
its default if it is available.
|
Object |
resolveConstructorArgument(String paramName,
Class<?> paramType,
NativeWebRequest request) |
boolean |
supportsParameter(MethodParameter parameter)
Returns
true if the parameter is annotated with
ModelAttribute or, if in default resolution mode, for any
method parameter that is not a simple type. |
boolean |
supportsReturnType(MethodParameter returnType)
Return
true if there is a method-level @ModelAttribute
or, in default resolution mode, for any return value type that is not
a simple type. |
protected void |
validateIfApplicable(WebDataBinder binder,
MethodParameter parameter)
Validate the model attribute if applicable.
|
protected void |
validateValueIfApplicable(WebDataBinder binder,
MethodParameter parameter,
Class<?> targetType,
String fieldName,
Object value)
Validate the specified candidate value if applicable.
|
protected final Log logger
public ModelAttributeMethodProcessor(boolean annotationNotRequired)
annotationNotRequired - if "true", non-simple method arguments and
return values are considered model attributes with or without a
@ModelAttribute annotationpublic boolean supportsParameter(MethodParameter parameter)
true if the parameter is annotated with
ModelAttribute or, if in default resolution mode, for any
method parameter that is not a simple type.supportsParameter in interface HandlerMethodArgumentResolverparameter - the method parameter to checktrue if this resolver supports the supplied parameter;
false otherwise@Nullable public final Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer, NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception
@java.validation.Valid is present on the argument.resolveArgument in interface HandlerMethodArgumentResolverparameter - the method parameter to resolve. This parameter must
have previously been passed to HandlerMethodArgumentResolver.supportsParameter(org.springframework.core.MethodParameter) which must
have returned true.mavContainer - the ModelAndViewContainer for the current requestwebRequest - the current requestbinderFactory - a factory for creating WebDataBinder instancesnull if not resolvableBindException - if data binding and validation result in an error
and the next method parameter is not of type ErrorsException - if WebDataBinder initialization failsprotected Object createAttribute(String attributeName, MethodParameter parameter, WebDataBinderFactory binderFactory, NativeWebRequest webRequest) throws Exception
The default implementation typically uses the unique public no-arg constructor
if available but also handles a "primary constructor" approach for data classes:
It understands the JavaBeans ConstructorProperties annotation as well as
runtime-retained parameter names in the bytecode, associating request parameters
with constructor arguments by name. If no such constructor is found, the default
constructor will be used (even if not public), assuming subsequent bean property
bindings through setter methods.
attributeName - the name of the attribute (never null)parameter - the method parameter declarationbinderFactory - for creating WebDataBinder instancewebRequest - the current requestnull)BindException - in case of constructor argument binding failureException - in case of constructor invocation failureconstructAttribute(Constructor, String, MethodParameter, WebDataBinderFactory, NativeWebRequest),
BeanUtils.findPrimaryConstructor(Class)protected Object constructAttribute(Constructor<?> ctor, String attributeName, MethodParameter parameter, WebDataBinderFactory binderFactory, NativeWebRequest webRequest) throws Exception
Called from
createAttribute(String, MethodParameter, WebDataBinderFactory, NativeWebRequest)
after constructor resolution.
ctor - the constructor to useattributeName - the name of the attribute (never null)binderFactory - for creating WebDataBinder instancewebRequest - the current requestnull)BindException - in case of constructor argument binding failureException - in case of constructor invocation failureprotected void bindRequestParameters(WebDataBinder binder, NativeWebRequest request)
binder - the data binder instance to use for the bindingrequest - the current request@Nullable public Object resolveConstructorArgument(String paramName, Class<?> paramType, NativeWebRequest request) throws Exception
Exceptionprotected void validateIfApplicable(WebDataBinder binder, MethodParameter parameter)
The default implementation checks for @javax.validation.Valid,
Spring's Validated,
and custom annotations whose name starts with "Valid".
binder - the DataBinder to be usedparameter - the method parameter declarationDataBinder.validate(Object...),
SmartValidator.validate(Object, Errors, Object...)protected void validateValueIfApplicable(WebDataBinder binder, MethodParameter parameter, Class<?> targetType, String fieldName, @Nullable Object value)
The default implementation checks for @javax.validation.Valid,
Spring's Validated,
and custom annotations whose name starts with "Valid".
binder - the DataBinder to be usedparameter - the method parameter declarationtargetType - the target typefieldName - the name of the fieldvalue - the candidate valuevalidateIfApplicable(WebDataBinder, MethodParameter),
SmartValidator.validateValue(Class, String, Object, Errors, Object...)protected boolean isBindExceptionRequired(WebDataBinder binder, MethodParameter parameter)
The default implementation delegates to isBindExceptionRequired(MethodParameter).
binder - the data binder used to perform data bindingparameter - the method parameter declarationtrue if the next method parameter is not of type ErrorsisBindExceptionRequired(MethodParameter)protected boolean isBindExceptionRequired(MethodParameter parameter)
parameter - the method parameter declarationtrue if the next method parameter is not of type Errorspublic boolean supportsReturnType(MethodParameter returnType)
true if there is a method-level @ModelAttribute
or, in default resolution mode, for any return value type that is not
a simple type.supportsReturnType in interface HandlerMethodReturnValueHandlerreturnType - the method return type to checktrue if this handler supports the supplied return type;
false otherwisepublic void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception
ModelAndViewContainer.handleReturnValue in interface HandlerMethodReturnValueHandlerreturnValue - the value returned from the handler methodreturnType - the type of the return value. This type must have
previously been passed to HandlerMethodReturnValueHandler.supportsReturnType(org.springframework.core.MethodParameter) which must
have returned true.mavContainer - the ModelAndViewContainer for the current requestwebRequest - the current requestException - if the return value handling results in an error