New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow an @ModelAttribute method to be invoked after the @RequestMapping method [SPR-5695] #10365

Closed
spring-issuemaster opened this Issue Apr 23, 2009 · 4 comments

Comments

Projects
None yet
2 participants
@spring-issuemaster
Copy link
Collaborator

spring-issuemaster commented Apr 23, 2009

Costin Leau opened SPR-5695 and commented

@ModelAttribute is used for common (static) data and is used before the request is passed to the controller.
It would nice to be able to use the same annotation after the handling process as well, to take care of common request data. The idea is to isolate the common model functionality in a separate method (such as dealing defaults) and leave the controller to focus only on the dynamic behaviour.

An example of handling the initial request and initializing defaults (if ModelAttribute would be used after) would be:

@ModelAttribute("bundleList) List<Bundle> bundleList(@ModelAttribute("selection")  SelectionCommand selectionCommand) {
    if (selectionCommand.getDisplayChoice() == null)
         selectionCommand.setDisplayChoice(BundleListingOptions.NAME);
   // display bundles using the display choice...
}

In this case, if @ModelAttribute would be used after the controller, the method could inspect the parameters and populate the model map itself (currently this needs to be handled in the controller, i.e.:

if (selection ...) {
  model.addAttribute("bundleList", listBundles());
})

To be backwards compatible, the annotation could have a new parameter added to it (an enum) that can indicate when the binding should occur, before or after the handler invocation.


Affects: 2.5.6

Issue Links:

  • #10965 Support for @ModelAttribute interdependency

3 votes, 5 watchers

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

spring-issuemaster commented May 10, 2010

Patras Vlad Sebastian commented

I would like this feature too. Something similar to referenceData of MVC 2. Maybe add another option to the annotation to specify if you want it to be called or not in case of a redirect (because you usually don't), or maybe add some way so it could get the view name.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

spring-issuemaster commented May 30, 2012

Rossen Stoyanchev commented

@ModelAttribute is used for common (static) data and is used before the request is passed to the controller.

Very importantly @ModelAttribute is also used to pre-load a command object (e.g. from the database) so the object is available for data binding when arguments to the @RequestMapping method are resolved. So the ability to invoke a @ModelAttribute method before @RequestMapping methods is quite essential to data binding.

The idea is to isolate the common model functionality in a separate method (such as dealing defaults) and leave the controller to focus only on the dynamic behaviour.

In most cases an @ModelAttribute method should not be called after a redirect or after binding and validation errors. That creates more rules and complexity and potentially leads to surprises. I don't think adding flags to @ModelAttribute would solve the problem and those flags wouldn't make sense when @ModelAttribute is used on method arguments.

Although I see what you're trying to achieve, remember that an @ModelAttribute method supports the same argument types as an @RequestMapping method but only one of its return values (i.e. returning an Object to be added to the model). That means you can declare an @ModelAttribute argument, which can cause data binding or validation errors and all of that would occur after the @RequestMapping method selected a view. You could have no option to change the view since you can only return an Object to be added to the model.

It would be much simpler in this case to call the separate method from the @RequestMapping method as necessary.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

spring-issuemaster commented May 2, 2014

Rossen Stoyanchev commented

Re-opening after realizing there may be an opportunity to support this as a natural extension of the solution for #10965.

The trigger for invoking a model attribute method after (and not before) would be a dependency on another model attribute and that is a command object in the @RequestMapping method signature.

This way there is no need have additional flags or enums on @ModelAttribute. We simply detect that the model attribute you depend on will be available after the @RequestMapping method is invoked.

This seems to fit the spirit of the pre-@MVC reference data method and the original description of this ticket.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

spring-issuemaster commented Jun 7, 2014

Rossen Stoyanchev commented

After implementing #10965 and some further thought (e.g. see here) I am closing this once again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment