2023-08-01 12:50:06 +08:00
|
|
|
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.
|
2022-04-03 22:19:52 +08:00
|
|
|
|
2023-08-01 12:50:06 +08:00
|
|
|
TIP: The model object, and its nested object graph is also sometimes referred to as a
|
2022-04-03 22:19:52 +08:00
|
|
|
_command object_, _form-backing object_, or _POJO_ (Plain Old Java Object).
|
|
|
|
|
2023-08-01 12:50:06 +08:00
|
|
|
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:
|
2022-04-03 22:19:52 +08:00
|
|
|
|
|
|
|
[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;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
----
|
|
|
|
|
2023-08-02 22:21:33 +08:00
|
|
|
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:
|
2022-04-03 22:19:52 +08:00
|
|
|
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes"]
|
|
|
|
----
|
|
|
|
@Controller
|
|
|
|
public class ChangeEmailController {
|
|
|
|
|
|
|
|
@InitBinder
|
|
|
|
void initBinder(WebDataBinder binder) {
|
|
|
|
binder.setAllowedFields("oldEmailAddress", "newEmailAddress");
|
|
|
|
}
|
|
|
|
|
|
|
|
// @RequestMapping methods, etc.
|
|
|
|
|
|
|
|
}
|
|
|
|
----
|
|
|
|
|
2023-08-01 12:50:06 +08:00
|
|
|
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.
|
2023-08-02 22:21:33 +08:00
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
}
|
|
|
|
----
|