DataBinder class
Copies input values, usually strings from a form or a query, onto the
properties of an @Introspected object, then validates it, collecting
every problem in one bindingResult.
Use it when the input is a flat map of strings rather than JSON: form
fields, query parameters, a CSV row. Each value is converted to the
property's type; text that cannot be converted becomes a typeMismatch
field error that keeps what was typed, instead of an exception. Rules
such as requiredFields and disallowedFields protect the object from
missing or unexpected input (a client must not set id or admin).
The web starter does not use it: JSON bodies are read by the
ObjectMapper and checked with @Valid(). Spring Boot uses it to
validate @ConfigurationProperties classes.
// A signup form: only known fields, `email` required, `id` never set
// by the client.
final form = SignupForm();
final binder = DataBinder(form, objectName: 'signup')
..requiredFields = ['email']
..disallowedFields = ['id']
..validators.add(BeanValidator())
..bind({'name': 'Ada', 'age': '36', 'address.city': 'Oslo'})
..validate();
if (binder.bindingResult.hasErrors) {
log.warning(binder.bindingResult.fieldErrors());
}
// {signup: form, BindingResult.signup: ...}; throws on errors.
final model = binder.close();
An immutable class (final fields, no setters) cannot be bound onto.
Create it from the values with construct instead: constructor
binding, Spring 6.1. It goes through the constructor the generator
describes for @Introspected classes, the one ObjectMapper uses:
// Start without a target; construct creates it.
final binder =
DataBinder(null, objectName: 'book', introspector: introspector)
..targetType = Book
..construct(MapValueResolver({'isbn': '978-0', 'title': 'Dune'}));
final book = binder.target as Book?; // null when a value was invalid
Spring (Java):
DataBinder binder = new DataBinder(form, "signup");
binder.setRequiredFields("email");
binder.setDisallowedFields("id");
binder.addValidators(validator);
MutablePropertyValues values = new MutablePropertyValues();
values.add("name", "Ada");
values.add("age", "36");
values.add("address.city", "Oslo");
binder.bind(values);
binder.validate();
BindingResult result = binder.getBindingResult();
Map<?, ?> model = binder.close(); // throws BindException on errors
DataBinder books = new DataBinder(null, "book");
books.setTargetType(ResolvableType.forClass(Book.class));
books.construct(valueResolver);
Constructors
- DataBinder(Object? target, {String objectName = defaultObjectName, BeanIntrospector? introspector, ConversionService? conversionService, MessageCodesResolver messageCodesResolver = const DefaultMessageCodesResolver()})
-
A binder for
target, or for an object construct creates whentargetisnull;objectNamenames it in error codes and the model.
Properties
-
allowedFields
↔ List<
String> ? -
The fields that may be bound, as patterns with
*wildcards (address.*); input for other fields is skipped.nullor empty allows every field, like Spring'ssetAllowedFields()with no patterns.getter/setter pair - autoGrowCollectionLimit ↔ int
-
The highest list index plus one that binding may create, 256 by
default (Spring's
DEFAULT_AUTO_GROW_COLLECTION_LIMIT), so input such asitems[999999]cannot make the binder allocate a huge list.getter/setter pair - autoGrowNestedPaths ↔ bool
-
Whether binding
address.cityoritems[2].skucreates anullnested object, list or map, and missing list elements, on the way;trueby default.getter/setter pair - bindingResult → BeanPropertyBindingResult
-
The errors of binding and validation, with the target; created on
first use for the current target. Read it after bind and
validate, or let close throw when it has errors.
no setter
- conversionService → ConversionService
-
Converts input values, usually strings, to the property types.
final
-
disallowedFields
↔ List<
String> -
Fields that are never bound, as patterns with
*wildcards, such asidor*.admin; they win over allowedFields. Matching ignores case and also catches the bracket form of a dotted path (roles[admin]forroles.admin), as Spring does since CVE-2022-22968. Empty by default.getter/setter pair - hashCode → int
-
The hash code for this object.
no setterinherited
- ignoreInvalidFields ↔ bool
-
Whether input for a path that cannot be reached, such as
address.citywhileaddressisnulland cannot be created, is skipped;falseby default, and bind throws for it.getter/setter pair - ignoreUnknownFields ↔ bool
-
Whether input for a field the target does not have (or a malformed
path such as
items[) is skipped;trueby default. Whenfalse, bind throws for it.getter/setter pair - introspector → BeanIntrospector
-
Describes the properties and constructors of the target's class and
of nested classes.
final
- messageCodesResolver → MessageCodesResolver
-
Builds the message codes of binding and validation errors.
final
- objectName → String
-
The name of the target in error codes (
NotBlank.signup.name) and in the model.final -
requiredFields
↔ List<
String> -
Fields the input must contain with a non-blank value; a missing one
gets a
requiredfield error. Empty by default. A field that is also disallowed counts as missing.getter/setter pair - runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
-
suppressedFields
→ List<
String> -
The input fields bind skipped because allowedFields or
disallowedFields rejected them, over all bind calls; useful to log
tampering attempts. Spring's
BindingResult.getSuppressedFields().no setter - target → Object?
-
The object values are bound onto;
nulluntil construct creates it, and stillnullwhen that failed.no setter - targetType ↔ Type?
-
The class construct creates; it must be
@Introspected. Set it before calling construct. Spring'ssetTargetType.getter/setter pair -
validators
→ List<
Validator> -
The validators validate runs, in order; usually the application's
BeanValidatorand, for rules in code, your own Validators. Empty by default, so nothing is checked until you add one.final
Methods
-
bind(
Map< String, Object?> values) → void -
Sets the target's properties from
values, whose keys are property paths (name,address.city,items[0].sku); problems become field errors in bindingResult instead of exceptions. -
close(
) → Map< String, Object?> - Ends binding: throws a BindException when bindingResult has errors, else returns the model map.
-
construct(
ValueResolver valueResolver) → void -
Creates the target, an instance of targetType, by calling its
constructor with values from
valueResolver: constructor binding, for classes with final fields. Spring'sDataBinder.construct. -
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
toString(
) → String -
A string representation of this object.
inherited
-
validate(
{List< Type> groups = const []}) → void - Runs each of validators that supports the target, adding the errors to bindingResult; does nothing when there is no target.
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited
Static Methods
-
canonicalPropertyName(
String name) → String -
namewith quotes and surrounding blanks removed from map keys and indexes:map['key'],map["key"]andmap[ key ]all becomemap[key]. -
simpleMatch(
String pattern, String text) → bool -
Whether
textmatchespattern, where*stands for any text (dots included) and everything else matches itself; the matching of allowedFields and disallowedFields. Case-sensitive. Spring'sPatternMatchUtils.simpleMatch.
Constants
- defaultObjectName → const String
-
The object name when none is given,
target(Spring'sDataBinder.DEFAULT_OBJECT_NAME).