Announcement Announcement Module
Collapse
No announcement yet.
Looking for more detail on how @ModelAttribute-annotated methods are called Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Looking for more detail on how @ModelAttribute-annotated methods are called

    I've read the relevant documentation, and a few relevant books, and all of them explain @ModelAttribute-annotated methods somewhat vaguely. I don't understand exactly when these methods are called, how it knows what parameters to pass, if any, and what exactly is done with the annotation parameter.

    I understand that they are called before @RequestMapping-annotated methods, and that the return value is stored into the "model" with the name given by the annotation parameter.

    What I'm not sure about is what scope that model bean gets, and if the method takes parameters, what parameter values are set, and how does it know what to send (perhaps the same sub-question)?

    I think it's odd that @ModelAttribute is used in two completely different ways (method and parameter) for somewhat different purposes. That adds to the confusion a bit, in my opinion.

  • #2
    actually, you can use @ModelAttribute in three different ways:
    method, parameter and return value.


    So you can do:
    Code:
    public @ModelAttribute("modelKey") Something getSomething(){
     return new Something();
    }

    To answer your question:

    The return value will be put in the request scope.

    It knows what to send because you specify it: it puts the return value of the method in the modelmap. It will use the name you specified, or the non-qualified class name of the objct that's returned.


    about the parameters:

    from http://docs.huihoo.com/javadoc/sprin...Attribute.html
    Originally posted by http://docs.huihoo.com/javadoc/spring/2.5/org/springframework/web/bind/annotation/ModelAttribute.html
    Can also be used to expose reference data to a web view through annotating accessor methods in a controller class which is based on RequestMapping annotated handler methods, with such accessor methods allowed to have any arguments that RequestMapping supports for handler methods, returning the model attribute value to expose.
    The following article explains it also:
    http://www.infoq.com/articles/spring-2.5-ii-spring-mvc

    I hope this answers your question(s)
    Last edited by davymeers; May 15th, 2009, 03:17 PM. Reason: added other link

    Comment


    • #3
      That all explains the two usages that I understand (including the return-value one I didn't mention), however it still doesn't address the usage that is confusing to me.

      I'll cite a code excerpt from an article I recently read, at http://blog.jteam.nl/2009/05/14/simp...pring-mvc-2-5/ :

      Code:
      @ModelAttribute(“user”)
      public User formBackingObject(Long id) {
          if (id != null) {
              return userDao.findById(id);
          }
          return new User();
      }
      This method takes a single "Long id" parameter. When this method is called just before the @RequestMapping-annotated method, where is it going to get the "id" value from to send to this method? I see that the method checks for a NULL value. Perhaps this is called under two different circumstances?

      Comment


      • #4
        did you test this code?

        according to the link i provided about the @ModelAttribute those methods can have any arguments that RequestMapping supports for handler methods.

        Those are the following: (Source: http://static.springsource.org/sprin...stMapping.html)
        Originally posted by http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/web/bind/annotation/RequestMapping.html
        * Request and/or response objects (Servlet API or Portlet API). You may choose any specific request/response type, e.g. ServletRequest / HttpServletRequest or PortletRequest / ActionRequest / RenderRequest. Note that in the Portlet case, an explicitly declared action/render argument is also used for mapping specific request types onto a handler method (in case of no other information given that differentiates between action and render requests).
        * Session object (Servlet API or Portlet API): either HttpSession or PortletSession. An argument of this type will enforce the presence of a corresponding session. As a consequence, such an argument will never be null. Note that session access may not be thread-safe, in particular in a Servlet environment: Consider switching the "synchronizeOnSession" flag to "true" if multiple requests are allowed to access a session concurrently.
        * WebRequest or NativeWebRequest. Allows for generic request parameter access as well as request/session attribute access, without ties to the native Servlet/Portlet API.
        * Locale for the current request locale (determined by the most specific locale resolver available, i.e. the configured LocaleResolver in a Servlet environment and the portal locale in a Portlet environment).
        * InputStream / Reader for access to the request's content. This will be the raw InputStream/Reader as exposed by the Servlet/Portlet API.
        * OutputStream / Writer for generating the response's content. This will be the raw OutputStream/Writer as exposed by the Servlet/Portlet API.
        * @RequestParam annotated parameters for access to specific Servlet/Portlet request parameters. Parameter values will be converted to the declared method argument type.
        * Map / Model / ModelMap for enriching the implicit model that will be exposed to the web view.
        * Command/form objects to bind parameters to: as bean properties or fields, with customizable type conversion, depending on InitBinder methods and/or the HandlerAdapter configuration - see the "webBindingInitializer" property on AnnotationMethodHandlerAdapter. Such command objects along with their validation results will be exposed as model attributes, by default using the non-qualified command class name in property notation (e.g. "orderAddress" for type "mypackage.OrderAddress"). Specify a parameter-level ModelAttribute annotation for declaring a specific model attribute name.
        * Errors / BindingResult validation results for a preceding command/form object (the immediate preceding argument).
        * SessionStatus status handle for marking form processing as complete (triggering the cleanup of session attributes that have been indicated by the SessionAttributes annotation at the handler type level).

        I did create similar methods like the one you showed (to be able to do a "new" and an "update" with the same controller), but i needed to add the @RequestParam before the long to make it work
        Last edited by davymeers; May 17th, 2009, 06:40 AM. Reason: corrected hyperlink

        Comment


        • #5
          I also read that blog and noticed this. The @RequestParam annotation should indeed be present for the 'id'.

          Comment


          • #6
            Originally posted by davymeers View Post
            actually, you can use @ModelAttribute in three different ways:
            method, parameter and return value.
            So you can do:
            Code:
            public @ModelAttribute("modelKey") Something getSomething(){
             return new Something();
            }
            By the way, I've searched all the documentation available to me, and I can't find a reference to this strategy, annotating the return value, as opposed to the method or the parameter. Is this strategy effectively identical to the "method" annotation?

            Comment


            • #7
              Originally posted by dkarr View Post
              By the way, I've searched all the documentation available to me, and I can't find a reference to this strategy, annotating the return value, as opposed to the method or the parameter. Is this strategy effectively identical to the "method" annotation?
              It is described in the javadoc (http://static.springsource.org/sprin...Attribute.html)
              Annotation that binds a method parameter or method return value to a named model attribute, exposed to a web view
              I am not sure if this strategy is identical to the "method" annotation (i haven't checked the source)

              Update:

              i just checked the source of org.springframework.web.servlet.mvc.annotation.Ann otationMethodHandlerAdapter and org.springframework.web.bind.annotation.support.Ha ndlerMethodInvoker.

              The big difference is: a method annotated with @ModelAttribute will be invoked for each request.

              But in the end both the return value of the method annotated with @ModelAttribute and the return value annotated with @ModelAttribute of a handlerMethod (== a method annotated with @RequestMapping) will be added to the model.
              Last edited by davymeers; May 17th, 2009, 07:52 AM. Reason: added explanation about internals

              Comment

              Working...
              X