Class ModelAttributeMethodProcessor
- All Implemented Interfaces:
HandlerMethodArgumentResolver
,HandlerMethodReturnValueHandler
- Direct Known Subclasses:
ServletModelAttributeMethodProcessor
@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 @jakarta.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
.
- Since:
- 3.1
- Author:
- Rossen Stoyanchev, Juergen Hoeller, Sebastien Deleuze, Vladislav Kisel
-
Field Summary
-
Constructor Summary
ConstructorDescriptionModelAttributeMethodProcessor
(boolean annotationNotRequired) Class constructor. -
Method Summary
Modifier and TypeMethodDescriptionprotected 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 theModelAndViewContainer
.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.final 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.resolveConstructorArgument
(String paramName, Class<?> paramType, NativeWebRequest request) boolean
supportsParameter
(MethodParameter parameter) Returnstrue
if the parameter is annotated withModelAttribute
or, if in default resolution mode, for any method parameter that is not a simple type.boolean
supportsReturnType
(MethodParameter returnType) Returntrue
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.
-
Field Details
-
logger
-
-
Constructor Details
-
ModelAttributeMethodProcessor
public ModelAttributeMethodProcessor(boolean annotationNotRequired) Class constructor.- Parameters:
annotationNotRequired
- if "true", non-simple method arguments and return values are considered model attributes with or without a@ModelAttribute
annotation
-
-
Method Details
-
supportsParameter
Returnstrue
if the parameter is annotated withModelAttribute
or, if in default resolution mode, for any method parameter that is not a simple type.- Specified by:
supportsParameter
in interfaceHandlerMethodArgumentResolver
- Parameters:
parameter
- the method parameter to check- Returns:
true
if this resolver supports the supplied parameter;false
otherwise
-
resolveArgument
@Nullable public final Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer, NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception Resolve the argument from the model or if not found instantiate it with its default if it is available. The model attribute is then populated with request values via data binding and optionally validated if@java.validation.Valid
is present on the argument.- Specified by:
resolveArgument
in interfaceHandlerMethodArgumentResolver
- Parameters:
parameter
- the method parameter to resolve. This parameter must have previously been passed toHandlerMethodArgumentResolver.supportsParameter(org.springframework.core.MethodParameter)
which must have returnedtrue
.mavContainer
- the ModelAndViewContainer for the current requestwebRequest
- the current requestbinderFactory
- a factory for creatingWebDataBinder
instances- Returns:
- the resolved argument value, or
null
if not resolvable - Throws:
BindException
- if data binding and validation result in an error and the next method parameter is not of typeErrors
Exception
- if WebDataBinder initialization fails
-
createAttribute
protected Object createAttribute(String attributeName, MethodParameter parameter, WebDataBinderFactory binderFactory, NativeWebRequest webRequest) throws Exception Extension point to create the model attribute if not found in the model, with subsequent parameter binding through bean properties (unless suppressed).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.- Parameters:
attributeName
- the name of the attribute (nevernull
)parameter
- the method parameter declarationbinderFactory
- for creating WebDataBinder instancewebRequest
- the current request- Returns:
- the created model attribute (never
null
) - Throws:
BindException
- in case of constructor argument binding failureException
- in case of constructor invocation failure- See Also:
-
constructAttribute
protected Object constructAttribute(Constructor<?> ctor, String attributeName, MethodParameter parameter, WebDataBinderFactory binderFactory, NativeWebRequest webRequest) throws Exception Construct a new attribute instance with the given constructor.Called from
createAttribute(String, MethodParameter, WebDataBinderFactory, NativeWebRequest)
after constructor resolution.- Parameters:
ctor
- the constructor to useattributeName
- the name of the attribute (nevernull
)parameter
- the method parameter declarationbinderFactory
- for creating WebDataBinder instancewebRequest
- the current request- Returns:
- the created model attribute (never
null
) - Throws:
BindException
- in case of constructor argument binding failureException
- in case of constructor invocation failure- Since:
- 5.1
-
bindRequestParameters
Extension point to bind the request to the target object.- Parameters:
binder
- the data binder instance to use for the bindingrequest
- the current request
-
resolveConstructorArgument
@Nullable public Object resolveConstructorArgument(String paramName, Class<?> paramType, NativeWebRequest request) throws Exception - Throws:
Exception
-
validateIfApplicable
Validate the model attribute if applicable.The default implementation checks for
@jakarta.validation.Valid
, Spring'sValidated
, and custom annotations whose name starts with "Valid".- Parameters:
binder
- the DataBinder to be usedparameter
- the method parameter declaration- See Also:
-
validateValueIfApplicable
protected void validateValueIfApplicable(WebDataBinder binder, MethodParameter parameter, Class<?> targetType, String fieldName, @Nullable Object value) Validate the specified candidate value if applicable.The default implementation checks for
@jakarta.validation.Valid
, Spring'sValidated
, and custom annotations whose name starts with "Valid".- Parameters:
binder
- the DataBinder to be usedparameter
- the method parameter declarationtargetType
- the target typefieldName
- the name of the fieldvalue
- the candidate value- Since:
- 5.1
- See Also:
-
isBindExceptionRequired
Whether to raise a fatal bind exception on validation errors.The default implementation delegates to
isBindExceptionRequired(MethodParameter)
.- Parameters:
binder
- the data binder used to perform data bindingparameter
- the method parameter declaration- Returns:
true
if the next method parameter is not of typeErrors
- See Also:
-
isBindExceptionRequired
Whether to raise a fatal bind exception on validation errors.- Parameters:
parameter
- the method parameter declaration- Returns:
true
if the next method parameter is not of typeErrors
- Since:
- 5.0
-
supportsReturnType
Returntrue
if there is a method-level@ModelAttribute
or, in default resolution mode, for any return value type that is not a simple type.- Specified by:
supportsReturnType
in interfaceHandlerMethodReturnValueHandler
- Parameters:
returnType
- the method return type to check- Returns:
true
if this handler supports the supplied return type;false
otherwise
-
handleReturnValue
public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception Add non-null return values to theModelAndViewContainer
.- Specified by:
handleReturnValue
in interfaceHandlerMethodReturnValueHandler
- Parameters:
returnValue
- the value returned from the handler methodreturnType
- the type of the return value. This type must have previously been passed toHandlerMethodReturnValueHandler.supportsReturnType(org.springframework.core.MethodParameter)
which must have returnedtrue
.mavContainer
- the ModelAndViewContainer for the current requestwebRequest
- the current request- Throws:
Exception
- if the return value handling results in an error
-