Currently (Spring Boot2.6.2) it is not possible to add flashmap attributes to a ModelAndView
.
In the ModelAndView
constructor, the flash attributes from a RedirectAttributesModelMap
are not merged into the regular ModelMap
contained in ModelAndView
.
The test in RequestMappingHandlerAdapter.getModelAndView
for RedirectAttributes
fails, because the ModelAndView
reads the attributes from the RedirectAttributesModelMap
and merges them into the already existing ModelMap
in ModelAndView
.
The only way now to cause the ModelMap
to be an instance of RedirectAttributes
is by adding a RedirectAttributes
to the Controller
method.
What was expected is that the RedirectAttributesModelMap
was passed to the ModelAndViewContainer
so it could be picked up by the test in RequestMappingHandlerAdapter.getModelAndView()
.
If a RedirectAttributesModelMap
could turn up in RequestMappingHandlerAdapter.getModelAndView
it would be a beautiful way to create a View
factory returning a ModelAndView
(with flash attributes) without having to signal this in the Controller
method. And providing a clean separation.
A workaround currently is to fetch the flashmap via RequestContextUtils
, but that looks like a kludge.
Comment From: rstoyanchev
ModelAndView
is a simple holder of name value pairs and is the basic contract for the DispatcherServlet
and related strategies like HandlerAdapter
and ViewResolver
. Flash attributes is a more opinionated solution that's supported mainly from annotated controllers where you are expected to have RedirectAttributes
injected.
I'm not sure what you're proposing from an API perspective, but adding flash attributes directly to a ModelAndView
implies that you're also creating the ModelAndView
within the controller method and I don't see why that's more convenient or necessary. More often we expect the model to be passed into the controller method so you can simply add to it and just return the view name in which case you can have RedirectAttributes
passed in.
Comment From: sijskes
In the case where the creation of the ModelAndView is delegated away from the controller, and is created based on tests in this delegate, ModelAndView is a perfect return value from this delegate. RedirectAttributesModelMap is not different opinionated as the ModelMap in ModelAndView. Attributes stored in Model are also passed to a redirect, so why not RedirectAttributesModelMap attributes.
What you seem to indicate is that you want Model and FlashMap 'contained' in the Controller, and block designs where ModelAndView (with flashmap attributes) are created in a controller delegate.
And this 'blockade' is exactly how it is currently implemented. The ModelMap (name,value pairs) contained in ModelAndView is not accessible and one can only add normal attributes to it. ModelAndView allows for a redirect view, but without the needed RedirectAttributesModelMap.flashAttributes.
I seek to change this, so one can create a redirect ModelAndView away from the controller, with the needed RedirectAttributesModelMap.flashAttributes.
I see no reason to allow ModalAndView attributes to be set, and to deny this to flash-attributes.
Comment From: rstoyanchev
There is no intent to block anything to be honest, only some decisions from a number of years ago. Trying to recollect, so previously there was confusion with attributes from the "default" model ending up in redirect URLs (see #11462 and many related issues, both before and follow-ups). A specific goal was to clearly separate redirects from rendering, and encourage never using from the "default" model on redirect which is also a security concern. The reason this relates to flash attributes is they both apply to redirects and need to be exposed in the same places.
Here you're returning ModelAndView
and therefore not using the "default" model, but if we did support methods to add redirect and flash attributes through ModelAndView they would be expected in related scenarios with a split Model and String or View
instance (one as input and the other as output, in both combinations), but then it gets tricky to separate "default" model from non-default model use and moreover Model
and ModelMap
aren't even in web modules so not an option to add web methods there.
In any case, it's been like this for a long time and not revisited much or discussed so I'm not keen to revisit the current arrangement in ModelAndView
and add more nuance. FWIW, based on the experience in WebFlux we added the Rendering API which can be created within a controller method like ModelAndView
and supports a variety of cases. If anything we could add something more along those lines.
I am also wondering if you've considered an approach with passing RedirectAtributes
into your delegate?
Comment From: spring-projects-issues
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Comment From: sijskes
this was not a request for support. a kludge like the one suggested was already implemented. As to opinionated opinions, it was a suggestion for a much needed improvement of a incomplete and wrong api.
Comment From: rstoyanchev
Thanks for the feedback. I've created #28324 to revisit this area in more detail for 6.0.