[ 
https://issues.apache.org/jira/browse/MYFACES-2645?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12854927#action_12854927
 ] 

Jakob Korherr commented on MYFACES-2645:
----------------------------------------

This is the email, which I sent to jsr-314-open:

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

> The view state is saved before encodeAll() is called on every UIViewParameter 
> in an AJAX request
> ------------------------------------------------------------------------------------------------
>
>                 Key: MYFACES-2645
>                 URL: https://issues.apache.org/jira/browse/MYFACES-2645
>             Project: MyFaces Core
>          Issue Type: Bug
>          Components: JSR-314
>    Affects Versions: 2.0.0-beta-3
>            Reporter: Jakob Korherr
>            Assignee: Jakob Korherr
>         Attachments: MYFACES-2645-spec-proposal.patch
>
>
> UIViewParameter calls setSubmittedValue() in encodeAll() to store the current 
> value of the view parameter in the state as the submitted value (this helps 
> UIViewParameter to restore its value on a postback). 
> UIViewParameter.encodeAll() itself is called by UIViewRoot.encodeEnd() for 
> every UIViewParameter in the view.
> If the current request is an ajax-request, the view state is currently 
> already generated in UIViewRoot.encodeChildren() (before 
> UIViewRoot.encodeEnd()). At this time the submitted value for every 
> UIViewParameter is null, because its encodeAll()-method was not called yet.
> Later, when UIViewRoot.encodeEnd() is called, UIViewParameter.encodeAll() is 
> called and it sets the submitted value correctly, but due to the fact that 
> the state has already been generated, these changes are dropped.
> This causes the value of every UIViewParameter to be set to null in the next 
> request, which will most likely end in validation problems with the required 
> validator.
> The related thread to this issue from the mailing list can be found at: 
> http://www.junlu.com/list/43/611590.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to