[jsr-314-open-mirror] [jsr-314-open] Fwd: State saving of UIViewParameter

Matthias Wessendorf matzew at apache.org
Thu Apr 8 08:57:30 EDT 2010


Since MyFaces committer "Jakob Korherr" has only read-access to this
list, I am forwarding this mail.

-Matthias

PS: we use this forwarding "work-around" instead of filing issues
against the spec (for discussions).

---------- Forwarded message ----------
From: Jakob Korherr <jakob.korherr at gmail.com>
Date: Thu, Apr 8, 2010 at 2:46 PM
Subject: State saving of UIViewParameter
To: Matthias Wessendorf <mwessendorf at gmail.com>


Hi,

Yesterday we received an issue about the state saving of an
UIViewParameter in combination with an AJAX request on the MyFaces
user list (see [1] for details). This opened some questions/problems:

UIViewParameter uses the submittedValue to store its value in the
state for the next postback, because obviously the view parameter
won't be in the request parameter map of the next request (which is
the postback). But because its submittedValue is null after the
conversions and validations, it has to be set again before the state
is generated. To accomplish that, the spec currently states to
override encodeAll() and make the call to setSubmittedValue() there.
In addition, encodeAll() has to be called in UIViewRoot.encodeEnd()
for every UIViewParameter in the view. This works perfectly for normal
requests, but when you are using an AJAX request the state is
generated before UIViewRoot.encodeEnd() is called an thus the
submittedValue for every UIViewParameter is null in the state. This
means that the value of every UIViewParameter will be null in the
following request.

Now the easiest solution to this problem, which I also already
committed to MyFaces trunk (again see [1] for details), is to do
mostly the same as in UIViewRoot.encodeEnd() just also in
PartialViewContext.
processPartial() when the PhaseId is RENDER_RESPONSE before the state
is generated to make it work for AJAX-requests.

However I don't really like this solution, because we have to think of
handling UIViewParameters in a special way every time we change
something on any render mechanism. Why don't we just override
saveState() on UIViewParameter and set the submittedValue there before
the state is saved. This will have the same result, but without the
code in UIViewRoot, PartialViewContext and UIViewParameter.encodeAll()
and without future headaches. I also already uploaded a patch for this
to the MyFaces issue at [1].


The second thing I want to bring up here is an issue I ran into while
testing the first one. Imagine you have a page with a required
UIViewParameter called input. You will get a validation error as long
as you don't access the view with ?input=abc. Now if you do that once,
"abc" will be saved as the submittedValue in the state of the
UIViewParameter for every postback and thus will be available for
every further postback. If you now access the view again with a GET
request (non-postback), but without ?input=abc, you will again get a
validation error. However, if you hit any button or link on the view
to generate another postback to the view, the validation error will be
gone, because UIViewParameter takes the value from before ("abc") out
of the model (managed-bean) and sets it in the state. Thus you haven't
provided it via ?input=abc, but you will now have a value of "abc" for
your UIViewParameter, which seems kinda wrong to me. The solution to
this one is to get the value from the model to set it as the
submittedValue in UIViewParameter only if the current request is a
postback. However I don't know if this really is an error or the
expected behaviour. I personally just think that it is weird.

Many thanks for looking at this!

Regards,
Jakob

[1] https://issues.apache.org/jira/browse/MYFACES-2645


-- 
Matthias Wessendorf

blog: http://matthiaswessendorf.wordpress.com/
sessions: http://www.slideshare.net/mwessendorf
twitter: http://twitter.com/mwessendorf



More information about the jsr-314-open-mirror mailing list