org.springframework.web.method.annotation

## Class ModelAttributeMethodProcessor

- java.lang.Object
- - org.springframework.web.method.annotation.ModelAttributeMethodProcessor

- All Implemented Interfaces:
    HandlerMethodArgumentResolver, HandlerMethodReturnValueHandler
  Direct Known Subclasses:
    ServletModelAttributeMethodProcessor

      public class ModelAttributeMethodProcessor
      extends Object
      implements HandlerMethodArgumentResolver, HandlerMethodReturnValueHandler

  Resolve `@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`.

  Since:
    3.1
  Author:
    Rossen Stoyanchev, Juergen Hoeller, Sebastien Deleuze, Vladislav Kisel

- - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `protected Log` | `logger`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `ModelAttributeMethodProcessor(boolean annotationNotRequired)` Class constructor.

  - ### Method Summary

    All Methods Instance Methods Concrete Methods
    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.

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Field Detail

    - #### logger

          protected final Log logger

  - ### Constructor Detail

    - #### 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 Detail

    - #### supportsParameter

          public 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.
      Specified by:
        `supportsParameter` in interface `HandlerMethodArgumentResolver`
      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 interface `HandlerMethodArgumentResolver`
      Parameters:
        `parameter` - 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 request
        `webRequest` - the current request
        `binderFactory` - a factory for creating `WebDataBinder` 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 type `Errors`
        `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 (never `null`)
        `parameter` - the method parameter declaration
        `binderFactory` - for creating WebDataBinder instance
        `webRequest` - the current request
      Returns:
        the created model attribute (never `null`)
      Throws:
        `BindException` - in case of constructor argument binding failure
        `Exception` - in case of constructor invocation failure
      See Also:
        `constructAttribute(Constructor, String, MethodParameter, WebDataBinderFactory, NativeWebRequest)`, `BeanUtils.findPrimaryConstructor(Class)`

    - #### 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 use
        `attributeName` - the name of the attribute (never `null`)
        `binderFactory` - for creating WebDataBinder instance
        `webRequest` - the current request
      Returns:
        the created model attribute (never `null`)
      Throws:
        `BindException` - in case of constructor argument binding failure
        `Exception` - in case of constructor invocation failure
      Since:
        5.1

    - #### bindRequestParameters

          protected void bindRequestParameters(WebDataBinder binder,
                                               NativeWebRequest request)

      Extension point to bind the request to the target object.
      Parameters:
        `binder` - the data binder instance to use for the binding
        `request` - the current request

    - #### resolveConstructorArgument

          @Nullable
          public Object resolveConstructorArgument(String paramName,
                                                             Class<?> paramType,
                                                             NativeWebRequest request)
                                                      throws Exception

      Throws:
        `Exception`

    - #### validateIfApplicable

          protected void validateIfApplicable(WebDataBinder binder,
                                              MethodParameter parameter)

      Validate the model attribute if applicable.

      The default implementation checks for `@javax.validation.Valid`, Spring's `Validated`, and custom annotations whose name starts with "Valid".

      Parameters:
        `binder` - the DataBinder to be used
        `parameter` - the method parameter declaration
      See Also:
        `DataBinder.validate(Object...)`, `SmartValidator.validate(Object, Errors, Object...)`

    - #### 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 `@javax.validation.Valid`, Spring's `Validated`, and custom annotations whose name starts with "Valid".

      Parameters:
        `binder` - the DataBinder to be used
        `parameter` - the method parameter declaration
        `targetType` - the target type
        `fieldName` - the name of the field
        `value` - the candidate value
      Since:
        5.1
      See Also:
        `validateIfApplicable(WebDataBinder, MethodParameter)`, `SmartValidator.validateValue(Class, String, Object, Errors, Object...)`

    - #### isBindExceptionRequired

          protected boolean isBindExceptionRequired(WebDataBinder binder,
                                                    MethodParameter parameter)

      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 binding
        `parameter` - the method parameter declaration
      Returns:
        `true` if the next method parameter is not of type `Errors`
      See Also:
        `isBindExceptionRequired(MethodParameter)`

    - #### isBindExceptionRequired

          protected boolean isBindExceptionRequired(MethodParameter parameter)

      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 type `Errors`
      Since:
        5.0

    - #### supportsReturnType

          public 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.
      Specified by:
        `supportsReturnType` in interface `HandlerMethodReturnValueHandler`
      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 the `ModelAndViewContainer`.
      Specified by:
        `handleReturnValue` in interface `HandlerMethodReturnValueHandler`
      Parameters:
        `returnValue` - the value returned from the handler method
        `returnType` - 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 request
        `webRequest` - the current request
      Throws:
        `Exception` - if the return value handling results in an error