19.3 Unexpected
<jsp:setProperty> Behavior
The <jsp:setProperty> action can automatically set all
properties in a bean with names matching the names of the
parameters received with the request. This is a great feature
that's used in many of the examples in this book, but unless
you know how it works behind the scenes, you can be in for a
surprise.
When the <jsp:setProperty>
code is invoked, it gets a list of all request parameter names
and uses bean introspection to find the corresponding property
setter methods. It then calls all setter methods to set the
properties to the values of the parameters. This means that if
you have a property in your bean that doesn't match a
parameter, the setter method for this property is not called.
In most cases, this is not surprising. However, if the
parameter is present in some requests but not in others,
things may get a bit confusing. This is the case with
parameters corresponding to checkbox, radio button, and
selection list elements in an HTML form. If this type of
element is selected, the browser sends a parameter with the
element's name and the value of the selected item. If the
element is not selected, it doesn't send a parameter at all.
For example, let's say you have a bean with
an indexed property, such as the projects property in
the com.ora.jsp.beans.emp.EmployeeBean used in Chapter
12. This bean is kept in the session scope. The user can
change the value of the property through a group of checkboxes
in a form. To unregister all projects, the user deselects all
checkboxes and submits the form. You may think the following
code would then clear the property (setting it to
null): <jsp:setProperty name="validUser" property="*" />
Yet it doesn't. Without any checkbox
selections, the projects parameter is not sent, and
the corresponding property setter method is not called. This
is so even if you explicitly specify the property and request
parameter names: <jsp:setProperty name="validUser" property="projects"
param="projects" />
The workaround (described in Chapter
12) is to use the JSTL <c:set> action
instead, with an EL expression to explicitly set the property
to either the array of parameter values representing selected
checkboxes or null if none is selected: <c:set target="validUser" property="projects"
value="${paramValues.projects}" />
If you have been developing web applications
for a while, you may not think the
<jsp:setProperty> behavior is so surprising. It
behaves the same way, however, even when a parameter matching
a property is received, but its value is an empty string. It
happens to text fields the user leaves empty.
If you have properties matching text fields,
make sure the code that uses the values of the corresponding
properties can deal with null values or initialize
them to empty strings. If you keep a bean like this in a scope
other than the page and request scopes (where a new instance
is created for each request), also be aware that the user
can't clear the property by erasing the field in a form. One
possible workaround is to define a reset property
with a setter method that clears all properties. You then call
it explicitly like this in the JSP page before setting the
other properties: <jsp:setProperty name="validUser" property="reset"
value="any value" />
<jsp:setProperty name="validUser" property="*" />
All properties are first reset by the first
<jsp:setProperty> action and then all
properties matching request parameters are set by the second
action.
|