Fix issue with resolving Errors controller argument
The ErrorsMethodArgumentResolver expects the preceding @ModelAttribute in the controller method signature to be the last one added in the model -- an assumption that can break if a model attribute is added earlier (e.g. through a @ModelAttribute method) and more attributes are added as well. This fix ensures when an @ModelAttribute is resolved as a controller method argument it has the highest index in the model. Issue: SPR-9378 Backport Issue: SPR-9687
This commit is contained in:
@@ -17,10 +17,10 @@
|
||||
package org.springframework.web.method.annotation;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
@@ -31,7 +31,6 @@ import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||
import org.springframework.web.bind.support.WebRequestDataBinder;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.method.annotation.ModelFactory;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
@@ -113,7 +112,12 @@ public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResol
|
||||
}
|
||||
}
|
||||
|
||||
mavContainer.addAllAttributes(binder.getBindingResult().getModel());
|
||||
// Add resolved attribute and BindingResult at the end of the model
|
||||
|
||||
Map<String, Object> bindingResultModel = binder.getBindingResult().getModel();
|
||||
mavContainer.removeAttributes(bindingResultModel);
|
||||
mavContainer.addAllAttributes(bindingResultModel);
|
||||
|
||||
return binder.getTarget();
|
||||
}
|
||||
|
||||
|
||||
@@ -223,6 +223,18 @@ public class ModelAndViewContainer {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the given attributes from the model.
|
||||
*/
|
||||
public ModelAndViewContainer removeAttributes(Map<String, ?> attributes) {
|
||||
if (attributes != null) {
|
||||
for (String key : attributes.keySet()) {
|
||||
getModel().remove(key);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the underlying model contains the given attribute name.
|
||||
* @see ModelMap#containsAttribute(String)
|
||||
|
||||
Reference in New Issue
Block a user