Class ModelAttributeMethodProcessor

java.lang.Object
org.springframework.web.method.annotation.ModelAttributeMethodProcessor
All Implemented Interfaces:
HandlerMethodArgumentResolver, HandlerMethodReturnValueHandler

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 @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 Details

    • logger

      protected final Log 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

      public boolean supportsParameter(org.springframework.core.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(org.springframework.core.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:
      org.springframework.validation.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, org.springframework.core.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:
      org.springframework.validation.BindException - in case of constructor argument binding failure
      Exception - in case of constructor invocation failure
      See Also:
    • constructAttribute

      protected Object constructAttribute(Constructor<?> ctor, String attributeName, org.springframework.core.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:
      org.springframework.validation.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, org.springframework.core.MethodParameter parameter)
      Validate the model attribute if applicable.

      The default implementation checks for @jakarta.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, org.springframework.core.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'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:
    • isBindExceptionRequired

      protected boolean isBindExceptionRequired(WebDataBinder binder, org.springframework.core.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

      protected boolean isBindExceptionRequired(org.springframework.core.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(org.springframework.core.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, org.springframework.core.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