Spring Framework
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

91 lines
3.1 KiB

xref:core/validation/beans-beans.adoc#beans-binding[Data binding] for web requests involves
binding request parameters to a model object. By default, request parameters can be bound
to any public property of the model object, which means malicious clients can provide
extra values for properties that exist in the model object graph, but are not expected to
be set. This is why model object design requires careful consideration.
TIP: The model object, and its nested object graph is also sometimes referred to as a
_command object_, _form-backing object_, or _POJO_ (Plain Old Java Object).
A good practice is to use a _dedicated model object_ rather than exposing your domain
model such as JPA or Hibernate entities for web data binding. For example, on a form to
change an email address, create a `ChangeEmailForm` model object that declares only
the properties required for the input:
[source,java,indent=0,subs="verbatim,quotes"]
----
public class ChangeEmailForm {
private String oldEmailAddress;
private String newEmailAddress;
public void setOldEmailAddress(String oldEmailAddress) {
this.oldEmailAddress = oldEmailAddress;
}
public String getOldEmailAddress() {
return this.oldEmailAddress;
}
public void setNewEmailAddress(String newEmailAddress) {
this.newEmailAddress = newEmailAddress;
}
public String getNewEmailAddress() {
return this.newEmailAddress;
}
}
----
Another good practice is to apply
xref:core/validation/beans-beans.adoc#beans-constructor-binding[constructor binding],
which uses only the request parameters it needs for constructor arguments, and any other
input is ignored. This is in contrast to property binding which by default binds every
request parameter for which there is a matching property.
If neither a dedicated model object nor constructor binding is sufficient, and you must
use property binding, we strongy recommend registering `allowedFields` patterns (case
sensitive) on `WebDataBinder` in order to prevent unexpected properties from being set.
For example:
[source,java,indent=0,subs="verbatim,quotes"]
----
@Controller
public class ChangeEmailController {
@InitBinder
void initBinder(WebDataBinder binder) {
binder.setAllowedFields("oldEmailAddress", "newEmailAddress");
}
// @RequestMapping methods, etc.
}
----
You can also register `disallowedFields` patterns (case insensitive). However,
"allowed" configuration is preferred over "disallowed" as it is more explicit and less
prone to mistakes.
By default, constructor and property binding are both used. If you want to use
constructor binding only, you can set the `declarativeBinding` flag on `WebDataBinder`
through an `@InitBinder` method either locally within a controller or globally through an
`@ControllerAdvice`. Turning this flag on ensures that only constructor binding is used
and that property binding is not used unless `allowedFields` patterns are configured.
For example:
[source,java,indent=0,subs="verbatim,quotes"]
----
@Controller
public class MyController {
@InitBinder
void initBinder(WebDataBinder binder) {
binder.setDeclarativeBinding(true);
}
// @RequestMapping methods, etc.
}
----