diff --git a/spring-context/src/main/java/org/springframework/validation/DataBinder.java b/spring-context/src/main/java/org/springframework/validation/DataBinder.java index 207324ab86..fa68a11062 100644 --- a/spring-context/src/main/java/org/springframework/validation/DataBinder.java +++ b/spring-context/src/main/java/org/springframework/validation/DataBinder.java @@ -153,6 +153,8 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter { @Nullable private ExtendedTypeConverter typeConverter; + private boolean declarativeBinding = false; + private boolean ignoreUnknownFields = true; private boolean ignoreInvalidFields = false; @@ -425,6 +427,28 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter { return getInternalBindingResult(); } + /** + * Set whether to bind only fields explicitly intended for binding including: + *
Default is "false". Turn this on to limit binding to constructor
+ * parameters and allowed fields.
+ * @since 6.1
+ */
+ public void setDeclarativeBinding(boolean declarativeBinding) {
+ this.declarativeBinding = declarativeBinding;
+ }
+
+ /**
+ * Return whether to bind only fields intended for binding.
+ * @since 6.1
+ */
+ public boolean isDeclarativeBinding() {
+ return this.declarativeBinding;
+ }
/**
* Set whether to ignore unknown fields, that is, whether to ignore bind
@@ -1031,11 +1055,24 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
* @see #doBind(org.springframework.beans.MutablePropertyValues)
*/
public void bind(PropertyValues pvs) {
+ if (shouldNotBindPropertyValues()) {
+ return;
+ }
MutablePropertyValues mpvs = (pvs instanceof MutablePropertyValues mutablePropertyValues ?
mutablePropertyValues : new MutablePropertyValues(pvs));
doBind(mpvs);
}
+ /**
+ * Whether to not bind parameters to properties. Returns "true" if
+ * {@link #isDeclarativeBinding()} is on, and
+ * {@link #setAllowedFields(String...) allowedFields} are not configured.
+ * @since 6.1
+ */
+ protected boolean shouldNotBindPropertyValues() {
+ return (isDeclarativeBinding() && ObjectUtils.isEmpty(this.allowedFields));
+ }
+
/**
* Actual implementation of the binding process, working with the
* passed-in MutablePropertyValues instance.
diff --git a/spring-context/src/test/java/org/springframework/validation/DataBinderTests.java b/spring-context/src/test/java/org/springframework/validation/DataBinderTests.java
index a5cc5ba0a9..d5c174b9db 100644
--- a/spring-context/src/test/java/org/springframework/validation/DataBinderTests.java
+++ b/spring-context/src/test/java/org/springframework/validation/DataBinderTests.java
@@ -681,6 +681,23 @@ class DataBinderTests {
assertThat(dataBinder.convertIfNecessary(bean, String.class)).as("Type converter should have been used").isEqualTo("[Fred]");
}
+ @Test
+ void bindingInDeclarativeMode() throws BindException {
+ TestBean rod = new TestBean();
+ DataBinder binder = new DataBinder(rod);
+ binder.setDeclarativeBinding(true);
+
+ MutablePropertyValues pvs = new MutablePropertyValues();
+ pvs.add("name", "Rod");
+ pvs.add("age", "32x");
+
+ binder.bind(pvs);
+ binder.close();
+
+ assertThat(rod.getName()).isNull();
+ assertThat(rod.getAge()).isEqualTo(0);
+ }
+
@Test
void bindingWithAllowedFields() throws BindException {
TestBean rod = new TestBean();
diff --git a/spring-web/src/main/java/org/springframework/web/bind/ServletRequestDataBinder.java b/spring-web/src/main/java/org/springframework/web/bind/ServletRequestDataBinder.java
index f004de89c7..f0b361b09e 100644
--- a/spring-web/src/main/java/org/springframework/web/bind/ServletRequestDataBinder.java
+++ b/spring-web/src/main/java/org/springframework/web/bind/ServletRequestDataBinder.java
@@ -140,6 +140,9 @@ public class ServletRequestDataBinder extends WebDataBinder {
* @see #bind(org.springframework.beans.PropertyValues)
*/
public void bind(ServletRequest request) {
+ if (shouldNotBindPropertyValues()) {
+ return;
+ }
MutablePropertyValues mpvs = new ServletRequestParameterPropertyValues(request);
MultipartRequest multipartRequest = WebUtils.getNativeRequest(request, MultipartRequest.class);
if (multipartRequest != null) {
diff --git a/spring-web/src/main/java/org/springframework/web/bind/support/ConfigurableWebBindingInitializer.java b/spring-web/src/main/java/org/springframework/web/bind/support/ConfigurableWebBindingInitializer.java
index 8a3220f8ff..293bb83a0c 100644
--- a/spring-web/src/main/java/org/springframework/web/bind/support/ConfigurableWebBindingInitializer.java
+++ b/spring-web/src/main/java/org/springframework/web/bind/support/ConfigurableWebBindingInitializer.java
@@ -44,6 +44,9 @@ public class ConfigurableWebBindingInitializer implements WebBindingInitializer
private boolean directFieldAccess = false;
+ @Nullable
+ private Boolean declarativeBinding;
+
@Nullable
private MessageCodesResolver messageCodesResolver;
@@ -99,6 +102,23 @@ public class ConfigurableWebBindingInitializer implements WebBindingInitializer
return this.directFieldAccess;
}
+ /**
+ * Set whether to bind only fields intended for binding as described in
+ * {@link org.springframework.validation.DataBinder#setDeclarativeBinding}.
+ * @since 6.1
+ */
+ public void setDeclarativeBinding(boolean declarativeBinding) {
+ this.declarativeBinding = declarativeBinding;
+ }
+
+ /**
+ * Return whether to bind only fields intended for binding.
+ * @since 6.1
+ */
+ public boolean isDeclarativeBinding() {
+ return (this.declarativeBinding != null ? this.declarativeBinding : false);
+ }
+
/**
* Set the strategy to use for resolving errors into message codes.
* Applies the given strategy to all data binders used by this controller.
@@ -197,6 +217,9 @@ public class ConfigurableWebBindingInitializer implements WebBindingInitializer
if (this.directFieldAccess) {
binder.initDirectFieldAccess();
}
+ if (this.declarativeBinding != null) {
+ binder.setDeclarativeBinding(this.declarativeBinding);
+ }
if (this.messageCodesResolver != null) {
binder.setMessageCodesResolver(this.messageCodesResolver);
}
diff --git a/spring-web/src/main/java/org/springframework/web/bind/support/WebExchangeDataBinder.java b/spring-web/src/main/java/org/springframework/web/bind/support/WebExchangeDataBinder.java
index 6367227dfa..38e0927519 100644
--- a/spring-web/src/main/java/org/springframework/web/bind/support/WebExchangeDataBinder.java
+++ b/spring-web/src/main/java/org/springframework/web/bind/support/WebExchangeDataBinder.java
@@ -93,6 +93,9 @@ public class WebExchangeDataBinder extends WebDataBinder {
* @return a {@code Mono