Some other user posted a similar question on this forum recently and even filed a bug (https://javaserverfaces.dev.java.net/issues/show_bug.cgi?id=82), but there's no response yet. The symptom is that if user clicks a commandButton with immediate="true", inputText fields in the form seem to be always using "cached" value and does not call the backing bean's getter method bound to the inputText fields to get their latest values. I would like to give another simple test case to illustrate this problem, and hopefully somebody can suggest some solution to this problem:
Then, the backing bean class is defined as follows:
publicclass Test {
public String cancel() {
System.out.println("cancel() called");
return "homepage";
}
public String save() {
System.out.println("save() called");
return "homepage";
}
private String field1;
private String field2;
public String getField1() {
field1 = readField1FromDatabase(); // read field1 from database
System.out.println("getField1() called; return " + field1);
return field1;
}
publicvoid setField1(String field1) {
System.out.println("setField1() called with " + field1);
this.field1 = field1;
}
public String getField2() {
field2 = readField2FromDatabase(); // read field2 from database
System.out.println("getField2() called; return " + field2);
return field2;
}
publicvoid setField2(String field2) {
System.out.println("setField2() called with " + field2);
this.field2 = field2;
}
}
Although not shown here, the methods readField1FromDatabase() and readField2FromDatabase() simply get field1 and field2's values from database -- let's assume there's a table with one row, and two fields, field1 and field2, and these two methods simply read from that table.
The relevent part of faces-cofig.xml is as follows:
1. Access url test.faces. Now I can see field1 and field2 both display correct value obtained from database.
2. Click "cancel" button, and I see homepage.faces.
3. Go to database, and change the values of field1 and field2 in the database.
4. Type in the url for test.faces or click a href link pointing to test.faces. I expect to getField1() and getField2() methods to be called and new values of field1 and field2 I updated in step 3 should be displayed. However, from the System.out.println() debug message, I can see that getField1() method is not called at all, and in my browser, I still see the OLD value of field1. Method getField2() is called, and its new value is displayed correctly.
The difference between field1 and field2 is that former is an inputText, and the later is an outputText. The behavior of outputText is correct, while inputText is not.
The above scenario is not artificial. This happens in our real application and we are deeply troubled by this issue. Any help will be greatly appreicated!
This isn't a bug. With an "immediate" request, the user input values have only made it as far as UIInput.getSubmittedValue(), and have not been converted much less pushed to the model. Basically, it's the same scenario as when user input fails validation: JSF redisplays the user-entered value without looking to the model.
If you need JSF to forget about the currently submitted value, you should call setSubmittedValue(null).
Re: caching of inputText when commandButton immediate=true is clicked
Jan 3, 2005 7:36 PM
(reply 3
of 22) (In reply to
#2 )
Thanks Adam for the reply.
I think this problem is not related to whether user input values have or have not reached the model. Please note that in step 4 of the test case, the user manually typed in the original url or clicked a href link leading to the original url. This is not a form submission or resubmission -- the browser is sending to the server a plain GET request, and it's not posting any data to the JSF page. It seems to me that in such case JSF should not attempt to restore the view, but instead should create a new/blank view. This is at least the behavior if in step 2 user clicked the regular "submit" button, i.e. the button without immediate="true" -- in that case, JSF actually does NOT restore the view and simply creates a blank view.
Re: caching of inputText when commandButton immediate=true is clicked
Jan 3, 2005 7:38 PM
(reply 4
of 22) (In reply to
#1 )
If I remove immediate="true", then in step 4 JSF will query the backing bean for both field1 and field2 (i.e. it calls both getField1() and getField2() methods), which is the expected behavior.
Re: caching of inputText when commandButton immediate=true is clicked
Jan 3, 2005 8:58 PM
(reply 5
of 22) (In reply to
#4 )
I have not tried your case, but it looks like a problem with JSF. In the meantime can you code around it by not using immediate = True. Assuming you are using it to bypass Validation and updating of model in the case where Cancel action happens. Can you move validation to Save action so Cancel action does not cause any validation issues. Using a request scope bean can get you around updating of model when not desired.
Re: caching of inputText when commandButton immediate=true is clicked
Jan 3, 2005 9:43 PM
(reply 6
of 22) (In reply to
#5 )
Thanks nboudani for the suggestion. I'm glad at least somebody agrees this might be a bug. :)
I agree moving validation (and conversion) to the save button can work around this problem (I'm already using a request scoped bean, by the way), but I feel it's not a good solution because 1) I would have to do this for all pages where a cancel button is present, and that essentially defeats the whole purpose of JSF's much touted conversion/validation mechanism, and 2) it makes conversion and validation code cluttered in save() method or its helper methods.
I can of course use other workaround -- such as making the cancel button a regular HTML button instead of a JSF commandButton. With HTML button I can bring user to the desired page without any JSF operation involved. Still, it's not a perfect workaround since I would have to hardcode the destination page inside the HTML, defeating the elegant arrangement of putting all navigation information in faces-config.xml.
Re: caching of inputText when commandButton immediate=true is clicked
Jan 4, 2005 8:25 AM
(reply 8
of 22) (In reply to
#3 )
Ah, I see what you're saying. It is actually quite connected to whether values have reached the model, since reaching the model also means the values are taken out of the UI layer, but that's not all of it. The problem you're encountering is one of a host of problems with server-side state saving in JSF 1.1. The EG is working on a better server-side state saving approach for JSF 1.2.
You can switch to client-side state saving to eliminate the problem; if the RI's implementation of client-side state saving is unacceptable, you can check out Oracle's ADF Faces (which I work on), which has a significantly better solution.
Re: caching of inputText when commandButton immediate=true is clicked
May 2, 2005 3:45 AM
(reply 9
of 22) (In reply to
#8 )
Hi,
I am having a similar problem. I need to retrieve certain data from the backend and display it on the screen. Validations need to be bypassed for doing this. After setting immediate='true' for the commandButton, I want to call the backend methods from the backing bean. However since the data entered in the text box has not been bound to the bean, I cannot do a getXX() for any property in the bean.
How can binding be forcefully done for the bean after bypassing the validation. This should be a common problem. Anybody can please give suggestion on how this can be done.
Putting all the validation code onto a button click would solve the issue but then I guess that defeats the whole purpose of the h:message funda.
Re: caching of inputText when commandButton immediate=true is clicked
Aug 15, 2005 7:16 AM
(reply 11
of 22) (In reply to
#10 )
Hi,
Are you sure this will work?
First, your remove syntax seems wrong.
Second, even if I remove that page from session map. the input value is still there. I bound a backing bean method to this reset or so-called clear button. In the backing bean, I not only cleares all the bounded bean properties, but also remove the page. In the navigation case, I redisplay the same removed page. All the input fields are still there.
Third, if I do not set the immediate attribute, the page will go through validation phase, then all the fields will be cleared as set by my backing bean method. But I really do not need the validation if I just want to clear the form fields.
Re: caching of inputText when commandButton immediate=true is clicked
Aug 15, 2005 7:55 AM
(reply 12
of 22) (In reply to
#10 )
hi Sreedhar,
I got to admit that I made a mistake by not returning a value in my backing bean method which is bound to the action of reset commandButton. The remove thing did work!
Re: caching of inputText when commandButton immediate=true is clicked
Oct 4, 2005 6:43 AM
(reply 13
of 22) (In reply to
#12 )
Hi hvquest,
I have this problema too. But, in my view point, it's a error project of Java Server Faces. Think about this situation:
- The user get a page, fulfil the fields and submit. Then the server respnses a page with validation errors. So, the user simply desists this page and clicks in menu to get (via GET method) other page. In other moment, in same session, he gets the first page again.
Well, my first page is dirty and I want clear it. The Java Server Faces don't supply a way to do this. So i need use the workaround to remove the page of sessionMap. But it's ineffective because I have that rebuild the components again.
I had pleasure if Java Server Faces designers could read this.
Re: caching of inputText when commandButton immediate=true is clicked
Jul 23, 2006 9:57 PM
(reply 14
of 22) (In reply to
#13 )
Hi there, I had the same problem and between us at work we spent 5 days trying to figure this out. The solution is:
The 'Cancel' commandButton (or commandLink) has immediate="true" The inputText fields do not specify immediate (and are therefore immediate="false") The action in the backing bean invoked on Cancel click must return an outcome, eg. "list" There must be a navigation rule in faces-config.xml for the action, eg. as follows
* sessionMap.remove("/Admin.jsp") is not necessary
If the action outcome string is null or cannot be found in faces-config.xml, then stale values from the component tree are re-displayed - the bane of many JSF programmers lives. Tinkering with the UIViewRoot seems to have no effect.
Hope this help...
- Adam.
This topic has
22
replies
on
2
pages.
1
|
2
|
Next »