提交 ea05e0b1 编写于 作者: R Rossen Stoyanchev

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
上级 ea2943fe
......@@ -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);
}
}
......
......@@ -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
......
......@@ -215,6 +215,32 @@ public class ModelFactoryTests {
assertNull(this.sessionAttributeStore.retrieveAttribute(this.webRequest, attributeName));
}
// SPR-12542
@Test
public void updateModelWhenRedirecting() throws Exception {
String attributeName = "sessionAttr";
String attribute = "value";
ModelAndViewContainer container = new ModelAndViewContainer();
container.addAttribute(attributeName, attribute);
String queryParam = "123";
String queryParamName = "q";
container.setRedirectModel(new ModelMap(queryParamName, queryParam));
container.setRedirectModelScenario(true);
WebDataBinder dataBinder = new WebDataBinder(attribute, attributeName);
WebDataBinderFactory binderFactory = mock(WebDataBinderFactory.class);
given(binderFactory.createBinder(this.webRequest, attribute, attributeName)).willReturn(dataBinder);
ModelFactory modelFactory = new ModelFactory(null, binderFactory, this.sessionAttrsHandler);
modelFactory.updateModel(this.webRequest, container);
assertEquals(queryParam, container.getModel().get(queryParamName));
assertEquals(1, container.getModel().size());
assertEquals(attribute, this.sessionAttributeStore.retrieveAttribute(this.webRequest, attributeName));
}
private String bindingResultKey(String key) {
return BindingResult.MODEL_KEY_PREFIX + key;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册