Elaboration on the subject
All of the tags that are designed to serve as 'value holders', i.e. tags like <h:inputText>
or <h:selectOneMenu>
, are backed up by UIInput
classes that implement a EditableValueHolder
interface. During Apply request values phase the user submitted values are extracted from request parameters and are set as submitted values of the appropriate component class by UIInput#setSubmittedValue
. If necessary, the values are converted beforehand by using Converter#getAsObject
.
Next, every 'value holder' component provides for a value
attribute, which is bidirectionally binding the value of the component with the property of the backing bean. For example, when the binding is of the form value="#{bean.prop}"
, then bean.getProp()
is called when component value need to be updated from a bean property and bean.setProp(value)
is called with value
derived from UIInput#getValue()
when model values are to be updated during Update model values phase.
All in all, UIInput
components require a bidirectional binding with a bean property via value
attribute of the appropriate JSF tag and this binding provides for access of data in the model tier via a value expression. This leaves us with value bindings of the form value="#{bean.prop}"
type.
Population of properties based on some method
How when you want to populate your bean properties not with the straight user-submitted values, but with the values modified by some method you are basically left with the following:
- Provide for a
Converter
and do a one-to-one mappings between bean properties and component values in Converter#getAsObject
and Converter#getAsString
. Don't forget to specify your converter in, for example, converter
attribute of your tag. As a usual point of reference, you can consult Communication in JSF 2.0;
- Do the converter-type transformations in a getter/setter pair, like in
public String getProp(String s) { return modifyPropValue(this.prop); }
and public void setProp(String s) { this.prop = modifyCompValue(s); }
. I would though strongly discourage to do that;
- Do the transformation in an action(listener) method during form submission. For this you can have a dummy binding with
dummyProp
bean property and do the this.prop = modifyCompValue(dummyProp)
in your action(listener) method. You can also note that having a dummy roperty is redundant and you can access the necessary request parameter via FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("id")
. Actually, the solution proposed in another answer is a special case of this transformation where the only thing in action method is population of converted value.