The original value is already converted by specification. The purpose
of a converter is to take an object from the back-end and change it to
a view (HTML typically) compatible value and then change the view
value back to a back-end value on submit.
It is the back-end developer's job to ensure the back-end value is
"converted". If you want the original value to be converted using a
JSF converter, then use the Application object to create a converter
from you backing bean when you load the data, and convert the value as
you wish.
The purpose of the value change event is to tell you if the user
changed something. The user changed something if the value they submit
after conversion is not the same as the value from the back-end.
You keep saying "converted original value", but that is an oxymoron by
JSF definition. If my component is a number input field, the converted
value is type Integer and the client value is type String. So the
converter converts between string and integer, not integer and
integer.
To be even more precise, for a converter to work properly the
following must be true:
Converter converter = ...
Object value = component.getValue();
String str = converter.getAsString(value);
Object value2 = converter.getAsObject(str);
if (value2.equals(value)) {
// converter is valid
}
On 7/6/07, Vladimir Isakovich <[EMAIL PROTECTED]> wrote:
Null vs empty string is not the only one case, the point I'm trying to make
here:
whenever the JSF framework is applying some data conversion (either the
converter was explicitly declared or not), it may (should) remember that
conversion rule, so that when that same page is submitted, the framework (I
mean JSF) will compare ( for the purpose of firing changeValueEvent) not the
original value with the new value but the converted original value with the
new value.
Yes this is an old issue with all previous frameworks, but I thought JSF
could be better. And thinking of the declared converters, cann't I find all
converters for a given UIComponent using JSF API. I did not try but I
thought it's doable.
vlad
On 7/6/07, Bryan Basham <[EMAIL PROTECTED]> wrote:
> The problem you are experiencing is true for any Java/Web
> framework. An HTTP request parameter does not understand
> what a Java null is but always uses the empty string "". So
> somewhere in your application (or framework) you have to
> handle the conversion from "" to null.
>
> When it comes to String values, null is not the same as ""
> so I would recommend that your backing beans be populated
> with "" instead of null when dealing with JSF. Alternatively,
> you could create a NullStringConverter which converts from
> "" to null.
>
> When it comes to non-String values, then your converter should
> return null from the getAsObject method when an "" is the
> request parameter.
>
> -Bryan
>
> vlad10 wrote:
> > I'm fresh with JSF,
> > just started building some prototypes with facelets 1.1.11, myfaces
> > 1.1.3/tomahawk 1.1.3.
> >
> > I'm getting this general feeling that the framework is missing some
> > important feature.
> > I may create an inputText and populate it with a null value, the
framework
> > conviniently will convert it into an empty string and populate my page.
> > However, on submit the valueChangeListener will fire with the reason
that
> > null is not the same as an empty string.
> > I have another example. This the initial value is not null. I may
explicitly
> > add a converter to that field, so the value stored in POJO as
jva.util.Date
> > or as a BigDecimal or anything else will be nicely displayed on the
screen,
> > but I'll face again the unwanted behavior of my valueChangeListener.
> > For the time being, I'm trying to compensate this deficiency in my app
by
> > adding some filtering in a utility class. At the moment it's in the
> > beginning, just checking null/empty string case:
> >
> > /**
> > * UIInput value is never null when submitted, but the POJO is
always
> > * initialized with nulls. This creates a false alarm by
> > valueChangeListeners.
> > * This method tries to compensate this deficiency.
> > * @param input
> > * @param rec
> > * @return
> > */
> > public static boolean isValueChanged(UIInput input, Object pojo) {
> > String name = input.getId();
> > Object val = BeanUtil.getBeanValue(pojo,name);
> > if (val == null)
> > if(StringUtils.isEmpty(input.getValue().toString()))
> > return false;
> > else
> > return true;
> > return ( input.getValue().toString().compareTo(val.toString())
!= 0);
> > }
> >
> > My question: am I missing something????
> > Do I really need to add another layer in my app, I may call it something
> > like JSF Frendly POJOs. I may perform all necessary conversions right
there
> > when moving data from DB to the screen, and then on submit perform the
> > opposit conversion when moving data back. I hope I can avoid that.
> > Is not it possible for a framework to 'remember' not just an oldValue,
but
> > also the conversion performed, so prior to comparing old/new values it
would
> > apply that same converter to the old value???
> > I think, this part has been missed.
> >
> > thanks
> > vlad
> >
>
>