34
34
* HTML checkboxes and select options: detecting that a field was part of
35
35
* the form, but did not generate a request parameter because it was empty.
36
36
* A field marker allows to detect that state and reset the corresponding
37
- * bean property accordingly.
37
+ * bean property accordingly. Default values, for parameters that are otherwise
38
+ * not present, can specify a value for the field other then empty.
38
39
*
39
40
* @author Juergen Hoeller
41
+ * @author Scott Andrews
40
42
* @since 1.2
41
43
* @see #registerCustomEditor
42
44
* @see #setAllowedFields
43
45
* @see #setRequiredFields
44
46
* @see #setFieldMarkerPrefix
47
+ * @see #setFieldDefaultPrefix
45
48
* @see ServletRequestDataBinder
46
49
*/
47
50
public class WebDataBinder extends DataBinder {
@@ -58,9 +61,19 @@ public class WebDataBinder extends DataBinder {
58
61
*/
59
62
public static final String DEFAULT_FIELD_MARKER_PREFIX = "_" ;
60
63
64
+ /**
65
+ * Default prefix that field default parameters start with, followed by the field
66
+ * name: e.g. "!subscribeToNewsletter" for a field "subscribeToNewsletter".
67
+ * <p>Default parameters differ from field markers in that they provide a default
68
+ * value instead of an empty value.
69
+ * @see #setFieldDefaultPrefix
70
+ */
71
+ public static final String DEFAULT_FIELD_DEFAULT_PREFIX = "!" ;
61
72
62
73
private String fieldMarkerPrefix = DEFAULT_FIELD_MARKER_PREFIX ;
63
74
75
+ private String fieldDefaultPrefix = DEFAULT_FIELD_DEFAULT_PREFIX ;
76
+
64
77
private boolean bindEmptyMultipartFiles = true ;
65
78
66
79
@@ -118,6 +131,32 @@ public String getFieldMarkerPrefix() {
118
131
return this .fieldMarkerPrefix ;
119
132
}
120
133
134
+ /**
135
+ * Specify a prefix that can be used for parameters that indicate default
136
+ * value fields, having "prefix + field" as name. The value of the default
137
+ * field is used when the field is not provided.
138
+ * <p>Default is "!", for "!FIELD" parameters (e.g. "!subscribeToNewsletter").
139
+ * Set this to null if you want to turn off the field defaults completely.
140
+ * <p>HTML checkboxes only send a value when they're checked, so it is not
141
+ * possible to detect that a formerly checked box has just been unchecked,
142
+ * at least not with standard HTML means. A default field is especially
143
+ * useful when a checkbox represents a non-boolean value.
144
+ * <p>The presence of a default parameter preempts the behavior of a field
145
+ * marker for the given field.
146
+ * @see #DEFAULT_FIELD_DEFAULT_PREFIX
147
+ * @see org.springframework.web.servlet.mvc.BaseCommandController#onBind
148
+ */
149
+ public void setFieldDefaultPrefix (String fieldDefaultPrefix ) {
150
+ this .fieldDefaultPrefix = fieldDefaultPrefix ;
151
+ }
152
+
153
+ /**
154
+ * Return the prefix for parameters that mark default fields.
155
+ */
156
+ public String getFieldDefaultPrefix () {
157
+ return this .fieldDefaultPrefix ;
158
+ }
159
+
121
160
/**
122
161
* Set whether to bind empty MultipartFile parameters. Default is "true".
123
162
* <p>Turn this off if you want to keep an already bound MultipartFile
@@ -139,16 +178,42 @@ public boolean isBindEmptyMultipartFiles() {
139
178
140
179
141
180
/**
142
- * This implementation performs a field marker check
181
+ * This implementation performs a field default and marker check
143
182
* before delegating to the superclass binding process.
183
+ * @see #checkFieldDefaults
144
184
* @see #checkFieldMarkers
145
185
*/
146
186
@ Override
147
187
protected void doBind (MutablePropertyValues mpvs ) {
188
+ checkFieldDefaults (mpvs );
148
189
checkFieldMarkers (mpvs );
149
190
super .doBind (mpvs );
150
191
}
151
192
193
+ /**
194
+ * Check the given property values for field defaults,
195
+ * i.e. for fields that start with the field default prefix.
196
+ * <p>The existence of a field defaults indicates that the specified
197
+ * value should be used if the field is otherwise not present.
198
+ * @param mpvs the property values to be bound (can be modified)
199
+ * @see #getFieldDefaultPrefix
200
+ */
201
+ protected void checkFieldDefaults (MutablePropertyValues mpvs ) {
202
+ if (getFieldDefaultPrefix () != null ) {
203
+ String fieldDefaultPrefix = getFieldDefaultPrefix ();
204
+ PropertyValue [] pvArray = mpvs .getPropertyValues ();
205
+ for (PropertyValue pv : pvArray ) {
206
+ if (pv .getName ().startsWith (fieldDefaultPrefix )) {
207
+ String field = pv .getName ().substring (fieldDefaultPrefix .length ());
208
+ if (getPropertyAccessor ().isWritableProperty (field ) && !mpvs .contains (field )) {
209
+ mpvs .addPropertyValue (field , pv .getValue ());
210
+ }
211
+ mpvs .removePropertyValue (pv );
212
+ }
213
+ }
214
+ }
215
+ }
216
+
152
217
/**
153
218
* Check the given property values for field markers,
154
219
* i.e. for fields that start with the field marker prefix.
0 commit comments