Allow binding=false on @ModelAttribute
Issue: SPR-13402
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,6 +22,7 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
import org.springframework.ui.Model;
|
||||
|
||||
/**
|
||||
@@ -49,6 +50,7 @@ import org.springframework.ui.Model;
|
||||
* access to a {@link Model} argument.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 2.5
|
||||
*/
|
||||
@Target({ElementType.PARAMETER, ElementType.METHOD})
|
||||
@@ -56,6 +58,12 @@ import org.springframework.ui.Model;
|
||||
@Documented
|
||||
public @interface ModelAttribute {
|
||||
|
||||
/**
|
||||
* Alias for {@link #name}.
|
||||
*/
|
||||
@AliasFor("name")
|
||||
String value() default "";
|
||||
|
||||
/**
|
||||
* The name of the model attribute to bind to.
|
||||
* <p>The default model attribute name is inferred from the declared
|
||||
@@ -63,7 +71,19 @@ public @interface ModelAttribute {
|
||||
* based on the non-qualified class name:
|
||||
* e.g. "orderAddress" for class "mypackage.OrderAddress",
|
||||
* or "orderAddressList" for "List<mypackage.OrderAddress>".
|
||||
* @since 4.3
|
||||
*/
|
||||
String value() default "";
|
||||
@AliasFor("value")
|
||||
String name() default "";
|
||||
|
||||
/**
|
||||
* Allows declaring data binding disabled directly on an
|
||||
* {@code @ModelAttribute} method parameter or on the attribute returned from
|
||||
* an {@code @ModelAttribute} method, both of which would prevent data
|
||||
* binding for that attribute.
|
||||
* <p>By default this is set to "true" in which case data binding applies.
|
||||
* Set this to "false" to disable data binding.
|
||||
*/
|
||||
boolean binding() default true;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -101,9 +101,18 @@ public class ModelAttributeMethodProcessor
|
||||
Object attribute = (mavContainer.containsAttribute(name) ? mavContainer.getModel().get(name) :
|
||||
createAttribute(name, parameter, binderFactory, webRequest));
|
||||
|
||||
if (!mavContainer.isBindingDisabled(name)) {
|
||||
ModelAttribute annotation = parameter.getParameterAnnotation(ModelAttribute.class);
|
||||
if (annotation != null && !annotation.binding()) {
|
||||
mavContainer.setBindingDisabled(name);
|
||||
}
|
||||
}
|
||||
|
||||
WebDataBinder binder = binderFactory.createBinder(webRequest, attribute, name);
|
||||
if (binder.getTarget() != null) {
|
||||
bindRequestParameters(binder, webRequest);
|
||||
if (!mavContainer.isBindingDisabled(name)) {
|
||||
bindRequestParameters(binder, webRequest);
|
||||
}
|
||||
validateIfApplicable(binder, parameter);
|
||||
if (binder.getBindingResult().hasErrors() && isBindExceptionRequired(binder, parameter)) {
|
||||
throw new BindException(binder.getBindingResult());
|
||||
|
||||
@@ -132,9 +132,11 @@ public final class ModelFactory {
|
||||
|
||||
while (!this.modelMethods.isEmpty()) {
|
||||
InvocableHandlerMethod modelMethod = getNextModelMethod(container).getHandlerMethod();
|
||||
ModelAttribute annot = modelMethod.getMethodAnnotation(ModelAttribute.class);
|
||||
String modelName = annot.value();
|
||||
if (container.containsAttribute(modelName)) {
|
||||
ModelAttribute annotation = modelMethod.getMethodAnnotation(ModelAttribute.class);
|
||||
if (container.containsAttribute(annotation.name())) {
|
||||
if (!annotation.binding()) {
|
||||
container.setBindingDisabled(annotation.name());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -142,6 +144,9 @@ public final class ModelFactory {
|
||||
|
||||
if (!modelMethod.isVoid()){
|
||||
String returnValueName = getNameForReturnValue(returnValue, modelMethod.getReturnType());
|
||||
if (!annotation.binding()) {
|
||||
container.setBindingDisabled(returnValueName);
|
||||
}
|
||||
if (!container.containsAttribute(returnValueName)) {
|
||||
container.addAttribute(returnValueName, returnValue);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
|
||||
package org.springframework.web.method.support;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.ui.Model;
|
||||
@@ -55,6 +57,9 @@ public class ModelAndViewContainer {
|
||||
|
||||
private boolean redirectModelScenario = false;
|
||||
|
||||
/* Names of attributes with binding disabled */
|
||||
private final Set<String> bindingDisabledAttributes = new HashSet<String>(4);
|
||||
|
||||
private HttpStatus status;
|
||||
|
||||
private final SessionStatus sessionStatus = new SimpleSessionStatus();
|
||||
@@ -133,6 +138,23 @@ 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.
|
||||
*/
|
||||
public boolean isBindingDisabled(String name) {
|
||||
return this.bindingDisabledAttributes.contains(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to use the default model or the redirect model.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user