0

During normal operation, everything works well on my Java EE note taking application running on GlassFish 4.1.2 with STATE_SAVING_METHOD set to server. I can open the ViewScoped Note.xhtml client in my Firefox browser; type text in the CKEditor field; select the [Create] button to save the note to the Derby database; edit the text and finally select the [Update] button to update the note information in the database.

The only issue that I have is when I edit my note and don't select create or update before the view expires. When this happens, the server reports a ViewExpiredException, and I see my default PrimeFaces error page.

Luckily, I discovered that I can perform the following steps to save the edited data.

  1. Select the browser back button.
  2. Select the browser refresh button.
  3. Select create or update buttons on the client.

When I select the browser back button, I see the previously edited page. I believe this is because the browser cached the page locally and is displaying the cached version of the previous page. The browser does not appear to communicate with the server when I select the back button.

If I select the create or update button immediately after selecting the back button, I see the ViewExpiredException again.

However, if I select the back button and then the refresh button, I can save or update my edited note.

I believe that selecting the refresh button creates a new view for the page but what I don't understand is why I don't lose my edits. When I select the refresh button, the server reports it creates a new backing bean and goes to the server to get the data for note. I would have expected the server to send this information back to the client and overwrite the edited values but it doesn't. After the refresh, a new view is created (I think?) but the client still has the edited values. When I select the update button the edited values are saved in the database.

I'm very glad that it works this way, because, if it didn't, I would lose my edits every time the view expired.

My question is why does it work this way. What I am missing about the JSF lifecyle that allows the browser to create a new view using a form containing edited data?

I read javax.faces.application.ViewExpiredException: View could not be restored before posting this question. This question builds on that question by specifically looking at what happened to edited data in a form when the page is refreshed when the view is expired which was not addressed in the original question.

Reed Elliott
  • 223
  • 2
  • 15
  • I read that question and also read Ch 2 of your book The Definitive Guide to JSF, however, neither source answers my question. I want to know why refreshing the page with edited data doesn't lose the edited data. The Definitive Guide states that in Phase 1 the component ".. will be instantiated based on the component tag defined in the view and populated with all attributes defined in the view." and that in Phase 6 JSF will "...build the full component tree based on the view definition." This makes me think that my edited values submitted during the non postback request would be overwritten. – Reed Elliott Oct 22 '18 at 09:31
  • I analyzed the network traffic and realized that selecting the refresh and navigating to the page both use an HTTP Get and both return the same response. The difference is that the browser maintains the edited form data on refresh but replaces the edited data on navigation. In other words, during a refresh, the browser ignores the response data and maintains the edited data on the form. This is surprising to me but a great feature. I'm also surprised that this topic is not discussed more often because it is essential to not losing data as you edit your form. – Reed Elliott Oct 24 '18 at 10:55
  • I cannot imagine the browser getting a new full response and ignoring it. That sounds like a **bug** in the browser! And it is not essential if the application is designed correctly. – Kukeltje Oct 24 '18 at 14:22
  • It turns out that this is standard Browser behavior. If you google "browser form refresh" you will see several references. I was caught up in this being the result of the JSF lifecycle when it turns out that JSF treats the page refresh exactly the same as the page non postback request but the browser treats the response differently. – Reed Elliott Oct 24 '18 at 19:06
  • Please provide an explicit link to be sure we read the same article – Kukeltje Oct 24 '18 at 19:08
  • The following stackoverflow link sums it up well: [Browser refresh behaviour](https://stackoverflow.com/questions/52213/browser-refresh-behaviour) – Reed Elliott Oct 24 '18 at 19:26

1 Answers1

0

To get rid of the set values when the user refreshes the page, set textbox/textarea autocomplete to off or create a function that will check whether the variables are null or not during the prerenderview event or in the constructor. If they aren't null, make them null.

Pramod
  • 129
  • 1
  • 12
  • Are you saying that a page refresh when the view is expired is processed like a postback request? I would have thought that it would be processed as a non postback request and therefore proceed from Phase 1 "Restore View" directly to Phase 6 "Render Reponse" and skipped Phase 2 "Apply Request Values". – Reed Elliott Oct 22 '18 at 09:46