📄 databinder.java
字号:
*/
public void setAllowedFields(String[] allowedFields) {
this.allowedFields = allowedFields;
if (logger.isDebugEnabled()) {
logger.debug("DataBinder restricted to binding allowed fields [" +
StringUtils.arrayToCommaDelimitedString(this.allowedFields) + "]");
}
}
/**
* Return the fields that should be allowed for binding.
* @return array of field names
*/
public String[] getAllowedFields() {
return allowedFields;
}
/**
* Register fields that are required for each binding process.
* @param requiredFields array of field names
*/
public void setRequiredFields(String[] requiredFields) {
this.requiredFields = requiredFields;
if (logger.isDebugEnabled()) {
logger.debug("DataBinder requires binding of required fields [" +
StringUtils.arrayToCommaDelimitedString(this.requiredFields) + "]");
}
}
/**
* Return the fields that are required for each binding process.
* @return array of field names
*/
public String[] getRequiredFields() {
return requiredFields;
}
/**
* Register the given custom property editor for all properties
* of the given type.
* @param requiredType type of the property
* @param propertyEditor editor to register
* @see org.springframework.beans.BeanWrapper#registerCustomEditor
*/
public void registerCustomEditor(Class requiredType, PropertyEditor propertyEditor) {
this.errors.getBeanWrapper().registerCustomEditor(requiredType, propertyEditor);
}
/**
* Register the given custom property editor for the given type and
* field, or for all fields of the given type.
* <p>If the field denotes an array or Collection, the PropertyEditor
* will get applied either to the array/Collection itself (the
* PropertyEditor has to create an array or Collection value) or to
* each element (the PropertyEditor has to create the element type),
* depending on the specified required type.
* <p>Note: Only one single registered custom editor per property path
* is supported. In case of a Collection/array, do not register an editor
* for both the Collection/array and each element on the same property.
* @param requiredType type of the property (can be null if a field is
* given but should be specified in any case for consistency checking)
* @param field name of the field (can also be a nested path), or
* null if registering an editor for all fields of the given type
* @param propertyEditor editor to register
* @see org.springframework.beans.BeanWrapper#registerCustomEditor
*/
public void registerCustomEditor(Class requiredType, String field, PropertyEditor propertyEditor) {
this.errors.getBeanWrapper().registerCustomEditor(requiredType, field, propertyEditor);
}
/**
* Set the strategy to use for resolving errors into message codes.
* Applies the given strategy to the underlying errors holder.
* @see BindException#setMessageCodesResolver
*/
public void setMessageCodesResolver(MessageCodesResolver messageCodesResolver) {
this.errors.setMessageCodesResolver(messageCodesResolver);
}
/**
* Bind the given property values to this binder's target.
* This call can create field errors, representing basic binding
* errors like a required field (code "required"), or type mismatch
* between value and bean property (code "typeMismatch").
* <p>Note that the given PropertyValues should be a throwaway instance:
* For efficiency, it will be modified to just contain allowed fields if it
* implements the MutablePropertyValues interface; else, an internal mutable
* copy will be created for this purpose. Pass in a copy of the PropertyValues
* if you want your original instance to stay unmodified in any case.
* @param pvs property values to bind.
*/
public void bind(PropertyValues pvs) {
// check for fields to bind
List allowedFieldsList = (this.allowedFields != null) ? Arrays.asList(this.allowedFields) : null;
MutablePropertyValues mpvs = (pvs instanceof MutablePropertyValues) ?
(MutablePropertyValues) pvs : new MutablePropertyValues(pvs);
PropertyValue[] pvArray = pvs.getPropertyValues();
for (int i = 0; i < pvArray.length; i++) {
String field = pvArray[i].getName();
if (!((allowedFieldsList != null && allowedFieldsList.contains(field)) || isAllowed(field))) {
mpvs.removePropertyValue(pvArray[i]);
if (logger.isWarnEnabled()) {
logger.warn("Field [" + pvArray[i] + "] has been removed from PropertyValues " +
"and will not be bound, because it has not been found in the list of allowed fields " +
allowedFieldsList);
}
}
}
pvs = mpvs;
// check for missing fields
if (this.requiredFields != null) {
for (int i = 0; i < this.requiredFields.length; i++) {
PropertyValue pv = pvs.getPropertyValue(this.requiredFields[i]);
if (pv == null || pv.getValue() == null ||
(pv.getValue() instanceof String && !StringUtils.hasText((String) pv.getValue()))) {
// create field error with code "required"
String field = this.requiredFields[i];
this.errors.addError(
new FieldError(this.errors.getObjectName(), field, "", true,
this.errors.resolveMessageCodes(MISSING_FIELD_ERROR_CODE, field),
getArgumentsForBindingError(field), "Field '" + field + "' is required"));
}
}
}
try {
// bind request parameters onto target object
this.errors.getBeanWrapper().setPropertyValues(pvs, this.ignoreUnknownFields);
}
catch (PropertyAccessExceptionsException ex) {
PropertyAccessException[] exs = ex.getPropertyAccessExceptions();
for (int i = 0; i < exs.length; i++) {
// create field with the exceptions's code, e.g. "typeMismatch"
String field = exs[i].getPropertyChangeEvent().getPropertyName();
this.errors.addError(
new FieldError(this.errors.getObjectName(), field, exs[i].getPropertyChangeEvent().getNewValue(), true,
this.errors.resolveMessageCodes(exs[i].getErrorCode(), field),
getArgumentsForBindingError(field), exs[i].getLocalizedMessage()));
}
}
}
/**
* Return if the given field is allowed for binding.
* Invoked for each passed-in property value.
* <p>The default implementation checks for "xxx*" and "*xxx" matches.
* Can be overridden in subclasses.
* <p>If the field is found in the allowedFields array as direct match,
* this method will not be invoked.
* @param field the field to check
* @return if the field is allowed
* @see #setAllowedFields
*/
protected boolean isAllowed(String field) {
if (this.allowedFields != null) {
for (int i = 0; i < this.allowedFields.length; i++) {
String allowed = this.allowedFields[i];
if ((allowed.endsWith("*") && field.startsWith(allowed.substring(0, allowed.length() - 1))) ||
(allowed.startsWith("*") && field.endsWith(allowed.substring(1, allowed.length())))) {
return true;
}
}
return false;
}
return true;
}
/**
* Return FieldError arguments for a binding error on the given field.
* Invoked for each missing required fields and each type mismatch.
* <p>Default implementation returns a DefaultMessageSourceResolvable
* with "objectName.field" and "field" as codes.
* @param field the field that caused the binding error
* @return the Object array that represents the FieldError arguments
* @see FieldError#getArguments
* @see org.springframework.context.support.DefaultMessageSourceResolvable
*/
protected Object[] getArgumentsForBindingError(String field) {
return new Object[] {
new DefaultMessageSourceResolvable(new String[] {getObjectName() + Errors.NESTED_PATH_SEPARATOR + field, field},
null, field)
};
}
/**
* Close this DataBinder, which may result in throwing
* a BindException if it encountered any errors
* @return the model Map, containing target object and Errors instance
* @throws BindException if there were any errors in the bind operation
* @see BindException#getModel
*/
public Map close() throws BindException {
if (this.errors.hasErrors()) {
throw this.errors;
}
return this.errors.getModel();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -