Improve @SessionAttributes support during redirect

Before this change attributes listed with @SessionAttributes would not
be saved in the session when there was a redirect and the controller
method declared a parameter of type RedirectAttributes.

This change ensures it's the "default" model that is always the one
checked for @SessionAttributes under all circumstances since
RedirectAttributes is really only meant to provide String values to
insert into or append to the the redirect URL.

Issue: SPR-12542
This commit is contained in:
Rossen Stoyanchev
2014-12-23 14:15:41 -05:00
parent ea2943feca
commit ea05e0b1ad
3 changed files with 43 additions and 3 deletions

View File

@@ -224,14 +224,15 @@ public final class ModelFactory {
* @throws Exception if creating BindingResult attributes fails
*/
public void updateModel(NativeWebRequest request, ModelAndViewContainer mavContainer) throws Exception {
ModelMap defaultModel = mavContainer.getDefaultModel();
if (mavContainer.getSessionStatus().isComplete()){
this.sessionAttributesHandler.cleanupAttributes(request);
}
else {
this.sessionAttributesHandler.storeAttributes(request, mavContainer.getModel());
this.sessionAttributesHandler.storeAttributes(request, defaultModel);
}
if (!mavContainer.isRequestHandled()) {
updateBindingResult(request, mavContainer.getModel());
if (!mavContainer.isRequestHandled() && mavContainer.getModel() == defaultModel) {
updateBindingResult(request, defaultModel);
}
}

View File

@@ -137,6 +137,19 @@ public class ModelAndViewContainer {
return (!this.redirectModelScenario || (this.redirectModel == null && !this.ignoreDefaultModelOnRedirect));
}
/**
* Return the "default" model created at instantiation.
* <p>In general it is recommended to use {@link #getModel()} instead which
* returns either the "default" model (template rendering) or the "redirect"
* model (redirect URL preparation). Use of this method may be needed for
* advanced cases when access to the "default" model is needed regardless,
* e.g. to save model attributes specified via {@code @SessionAttributes}.
* @return the default model, never {@code null}
*/
public ModelMap getDefaultModel() {
return this.defaultModel;
}
/**
* Provide a separate model instance to use in a redirect scenario.
* The provided additional model however is not used used unless