participate


JavaServer Faces - caching of inputText when commandButton immediate=true is clicked
<<   Back to Forum  |   Give us Feedback
10 Duke Stars available
This topic has 22 replies on 2 pages.    1 | 2 | Next »
lhh
Posts:4
Registered: 1/2/05
caching of inputText when commandButton immediate=true is clicked   
Jan 2, 2005 12:13 PM

 
Hello,

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:

First, create a JSF page test.jsp as follows:

<f:view>
<h:form>
<font color="red"><h:messages/></font><p>
 
Field 1: <h:inputText value="#{test.field1}"/><br>
Field 2: <h:outputText value="#{test.field2}"/><br>
 
<h:commandButton value="cancel" action="#{test.cancel}" immediate="true"/>
<h:commandButton value="save" action="#{test.save}"/>
</h:form>
 
</f:view>


Then, the backing bean class is defined as follows:

public class 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;
    }
    public void 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;
    }
    public void 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:

	<navigation-rule>
		<from-view-id>/test.jsp</from-view-id>	
		<navigation-case>
			<from-outcome>homepage</from-outcome>
			<to-view-id>/homepage.jsp</to-view-id>
			<redirect/>
		</navigation-case>
	</navigation-rule>


Now let's do the following:

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!

- lhh
 
ferric4
Posts:150
Registered: 2/15/01
Re: caching of inputText when commandButton immediate=true is clicked   
Jan 3, 2005 10:04 AM (reply 1 of 22)  (In reply to original post )

 
What happens when you remove the immediate="true" from the cancel button ?
 
awiner
Posts:51
Registered: 8/20/97
Re: caching of inputText when commandButton immediate=true is clicked   
Jan 3, 2005 1:22 PM (reply 2 of 22)  (In reply to original post )

 
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).

-- Adam Winer (JSF EG)
 
lhh
Posts:4
Registered: 1/2/05
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.
 
lhh
Posts:4
Registered: 1/2/05
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.
 
nboudani
Posts:226
Registered: 7/26/04
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.

Just a thought to get by.
 
lhh
Posts:4
Registered: 1/2/05
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.
 
ferric4
Posts:150
Registered: 2/15/01
Re: caching of inputText when commandButton immediate=true is clicked   
Jan 4, 2005 5:42 AM (reply 7 of 22)  (In reply to original post )

 
This Should work for you


<h:form>
<h:commandLink action="#{appControler.action}" immediate="true" actionListener="#{appControler.update}">xxxx</h:commandLink>
<h:inputText id="Testing" value="#{appControler.val}" immediate="true"/>
<h:message for="_id"/>
</h:form>


public class AppControler{

public void update(ActionEvent event){
FacesContext context = FacesContext.getCurrentInstance();
UIViewRoot root =context.getViewRoot();
root.processUpdates(context);
}-
 
awiner
Posts:51
Registered: 8/20/97
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.

-- Adam Winer (JSF EG)
 
brajan
Posts:1
Registered: 5/2/05
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.
 
sreedhargattu
Posts:9
Registered: 1/18/01
Re: caching of inputText when commandButton immediate=true is clicked   
Aug 15, 2005 2:20 AM (reply 10 of 22)  (In reply to #9 )

 
i had similar problem and i removed the jsp from the cache and it worked fine for me.

Map sessionMap = FacesContext.getCurrentInstance().getExternalContext().getCurrentInstanceExternalContext().getSessionMap()
sessionMap.remove("/yourjsp.jsp");
 
hvquest
Posts:4
Registered: 8/13/05
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.

Any more ideas?

Thanks.
 
hvquest
Posts:4
Registered: 8/13/05
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!

Thanks!
 
CesarACorreia
Posts:2
Registered: 9/22/05
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.
 
adam.buckley
Posts:4
Registered: 6/29/06
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
<navigation-rule>
	<from-view-id>/Admin.jsp</from-view-id>
	<navigation-case>
		<from-outcome>list</from-outcome>
		<to-view-id>/Admin.jsp</to-view-id>
	</navigation-case>
</navigation-rule>

* 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 »
Back to Forum
 
Read the Developer Forums Code of Conduct

Click to email this message Email this Topic

Edit this Topic
  
 
 
Forums Statistics
    Users Online : 23
  • Guests : 130

About Sun forums
  • Sun Forums is a large collection of user generated discussions. It is here to help you ask questions, find answers, and participate in discussions.

    Check out our guide on Getting started with Sun Forums for a full walkthrough of how to best leverage the benefits of this community.

Powered by Jive Forums