ModelAttributeMethodProcessor detects re-enabled binding declaration

Issue: SPR-16083
This commit is contained in:
Juergen Hoeller
2017-10-18 12:31:22 +02:00
parent ea00c7c6c8
commit bec1fc1852
4 changed files with 96 additions and 43 deletions

View File

@@ -115,11 +115,9 @@ public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResol
Assert.state(binderFactory != null, "ModelAttributeMethodProcessor requires WebDataBinderFactory");
String name = ModelFactory.getNameForParameter(parameter);
if (!mavContainer.isBindingDisabled(name)) {
ModelAttribute ann = parameter.getParameterAnnotation(ModelAttribute.class);
if (ann != null && !ann.binding()) {
mavContainer.setBindingDisabled(name);
}
ModelAttribute ann = parameter.getParameterAnnotation(ModelAttribute.class);
if (ann != null) {
mavContainer.setBinding(name, ann.binding());
}
Object attribute = null;

View File

@@ -44,6 +44,7 @@ import org.springframework.web.bind.support.SimpleSessionStatus;
* returns the redirect model instead of the default model.
*
* @author Rossen Stoyanchev
* @author Juergen Hoeller
* @since 3.1
*/
public class ModelAndViewContainer {
@@ -60,12 +61,13 @@ public class ModelAndViewContainer {
private boolean redirectModelScenario = false;
/* Names of attributes with binding disabled */
private final Set<String> bindingDisabledAttributes = new HashSet<>(4);
@Nullable
private HttpStatus status;
private final Set<String> noBinding = new HashSet<>(4);
private final Set<String> bindingDisabled = new HashSet<>(4);
private final SessionStatus sessionStatus = new SimpleSessionStatus();
private boolean requestHandled = false;
@@ -147,24 +149,6 @@ public class ModelAndViewContainer {
}
}
/**
* Register an attribute for which data binding should not occur, for example
* corresponding to an {@code @ModelAttribute(binding=false)} declaration.
* @param attributeName the name of the attribute
* @since 4.3
*/
public void setBindingDisabled(String attributeName) {
this.bindingDisabledAttributes.add(attributeName);
}
/**
* Whether binding is disabled for the given model attribute.
* @since 4.3
*/
public boolean isBindingDisabled(String name) {
return this.bindingDisabledAttributes.contains(name);
}
/**
* Whether to use the default model or the redirect model.
*/
@@ -205,15 +189,7 @@ public class ModelAndViewContainer {
}
/**
* Return the {@link SessionStatus} instance to use that can be used to
* signal that session processing is complete.
*/
public SessionStatus getSessionStatus() {
return this.sessionStatus;
}
/**
* Provide a HTTP status that will be passed on to with the
* Provide an HTTP status that will be passed on to with the
* {@code ModelAndView} used for view rendering purposes.
* @since 4.3
*/
@@ -230,6 +206,49 @@ public class ModelAndViewContainer {
return this.status;
}
/**
* Programmatically register an attribute for which data binding should not occur,
* not even for a subsequent {@code @ModelAttribute} declaration.
* @param attributeName the name of the attribute
* @since 4.3
*/
public void setBindingDisabled(String attributeName) {
this.bindingDisabled.add(attributeName);
}
/**
* Whether binding is disabled for the given model attribute.
* @since 4.3
*/
public boolean isBindingDisabled(String name) {
return (this.bindingDisabled.contains(name) || this.noBinding.contains(name));
}
/**
* Register whether data binding should occur for a corresponding model attribute,
* corresponding to an {@code @ModelAttribute(binding=true/false)} declaration.
* <p>Note: While this flag will be taken into account by {@link #isBindingDisabled},
* a hard {@link #setBindingDisabled} declaration will always override it.
* @param attributeName the name of the attribute
* @since 4.3.13
*/
public void setBinding(String attributeName, boolean enabled) {
if (!enabled) {
this.noBinding.add(attributeName);
}
else {
this.noBinding.remove(attributeName);
}
}
/**
* Return the {@link SessionStatus} instance to use that can be used to
* signal that session processing is complete.
*/
public SessionStatus getSessionStatus() {
return this.sessionStatus;
}
/**
* Whether the request has been handled fully within the handler, e.g.
* {@code @ResponseBody} method, and therefore view resolution is not