Handle ViewExpiredException in the background and restore form values - jsf

Is there a database-, primefaces- and "keep-session-alive"-free solution to prevent or to handle a ViewExpiredException silently in the background while restoring the form-inputs?
for example a user with a "stay logged-in cookie" would prefer not to be redirected to some kind of an error- or start-page; he fills out some form values, comes back in an hour and then, when he submits the form, the same view is re-created with its previous inputs and the submit-action of the underlying requestscope-bean is re-executed again.
i already took notice of omnifaces and mojarras
<o:enableRestorableView />
<f:view transient="true">
but as we talk about permanent logged-in users, i am not shure, if this would be the right approach.
thanks for pointing into the right direction.

the same view is re-created with its previous inputs and the submit-action of the underlying requestscope-bean is re-executed again
For exactly this requirement, transparently recreating and restoring an expired JSF form tied to a request scoped bean, stateless JSF as in <f:view transient="true"> is the correct solution.
The <o:enableRestorableView> is unnecessary in this specific case. It is only useful for transparently recreating and restoring an expired JSF form tied to a view scoped bean. You only still have to manually populate the view scoped bean properties based on request parameters in its #PostConstruct.
In other words, you don't need to mix those solutions. It does technically not make sense as view scoped beans are useless anyway in stateless JSF, they will behave like request scoped beans.
See also:
What is the usefulness of statelessness in JSF?
Restoring request parameters in #ViewScoped bean after session expires
javax.faces.application.ViewExpiredException: View could not be restored

Related

How to access #ViewScoped managed beans from Servlets?

I would like to access a view scope managed bean inside a Servlet.
I searched for similar question and got these ones:
how to get beans from view scope which uses FacesContext.getCurrentInstance(), inapplicable inside a Servlet because it should give a null result
JSF - get managed bean by name which treats all other scopes but not viewscope
I'm going to think it is not possible, is it ?
There is the simple solution to change that bean scope to session scope but it is a last chance because I'm worried by memory consumption.
My final need is the following: the managebean contains some data displayed in a dataTable. The same page should include the image (mandatory) of chart representation of those data. The image can be produced by a Servlet but it needs to access the data or reload them from the db.
I also tried the <p:graphicImage> from PrimeFaces 2.X but it is not compatible with viewscope beans. Any suggestion?
That's not possible, no. The view scope is tied to a specific JSF view, which is no means of in a plain HTTP servlet request. Note that you can't access concrete request scoped beans during a plain HTTP servlet request either, they would always return null.
The session scope is the best what you can get. You can just remove the attribute from the session scope once you're finished with it in the servlet.
session.removeAttribute("somename");

Access JSF ViewScoped managed bean from Servlet

How may I access a JSF ViewScoped managed bean from a Servlet?
(Assume that the managed bean in question has already been created, and still not been destroyed)
View-scoped variables are stored in the view map on the component tree. To access this data outside the view context you would have to create a JSF context and restore the view for the request. This involves rewriting much of the functionality provided by the JSF container.
JSF 2 provides mechanisms for interacting with server-side state without a page refresh: AJAX tags and the JSF JavaScript API. I would look at utilizing those if possible.
Alternatively, place the data into a scope that is easily accessible via servlets (the session.)
Since the view state is generally held in the session, it is likely technically possible to access the view state from here. But this would involve implementation-specific hacks that may not survive an upgrade of the underlying framework. I wouldn't even look at this as a solution.

Unnecessary Session Beans in Ajax Enabled JSF Frameworks

I've noticed that when using Ajax heavy JSF 1.2 implementations like Richfaces you're somehow forced to declare more managed beans than you'll want as Session scoped so that state can be maintained across multiple Ajax requests; there are components that will just stop working.
For instance, I developed this application lately in which I had to declare almost all my JSF Backing Beans as Session Scoped in order to have component "x" working. Is there a way out of this, do you consider it a bad practice, or is just the price to pay for having Ajax enabled component in JSF 1.2.
Thanks in advance.
Session scope beans increase memory usage.
Another available scope is View Scope - This allows to keep a state of a bean between requests, while the user is still on the same view.
If you are using JSF2, please consider using #ViewScope above the bean name:
#ViewScope
public class myBean{
..
}
If you use RichFaces and JSF1.2, consider using <a4j:keepAlive /> under <f:view> in the view. for example:
<a4j:keepAlive beanName = "#{myBean}"/>
Read more info here
Another option is to use Seam conversation. Also, I wouldn't say components stop working, they still work.. it's your logic that needs to maintain some sort of state on the server.

Preloading data into JSF page before response is rendered for the previous request

I am a beginner in JSF. I am building an application where on loggin on user details from the database are to be displayed in another JSP. I use a managed bean each for all of my jsp pages (JSF) I have defined thier scope as request in my faces-config XML. On logging in the details are verified by an actionListener method in my login page. Before leaving this method I am attempting to set attributes of the managed bean of the next page. But the state that I have set is not preserved in the second page. What am I missing out.
P.S. Please redirect me if this question was asked before and answered.
Thank you
The boundary between the two requests is when you return the navigation outcome from your managed bean action. Then a redirect (if configured so) is triggered to that outcome.
You have three options:
don't use <redirect /> in your navigation rules - thus you'll stay within the same request even when you show another page after submit. The downside is that this hurts user experience - if refresh is pressed, the ugly 'resubmit' dialog appears
use session scope - this is not harmful in small doses, but be careful not to have too many session-scoped beans.
use a conversation framework (like MyFaces Orchestra) - defines a custom scope called "conversation.access" - your data is accessible as long as it is needed.
use <a4j:keepAlive> from richfaces - preferred for ajax-requests.

JSF session scope beans with Tabbed browsing

We have the following problem...
Application's environment:
JSF, Richfaces, a4J
Consider having the following scenario:
The user logs into the system
The user navigates to a new page which consists of an a4j form containing a4j components, the user fills into the form but doesn't submit.
The user opens a new Tab and opens the same URL and fill in the new form with new data
The user returns to his first Tab and submits the information (Note: All beans are defined are session scope)
Result:
The submitted information is the information from the second Tab but submitted from the first Tab, which is expected as long as the beans are defined as session scope.
Problem:
We need to get the behavior of a request scope (i.e: dealing with new tab as a new request although the bean is defined as a session scope).
Notes:
When defining the bean scope as a request scope the partial Ajax response from individual components in the same form, resets the other components since they are not submitted yet.
Any suggestions ?
--
Thanks so much
This is a well known problem for Web applications.
Of course you can try to solve this problem using more custom code
but my quick suggestion is to use the seam framework which solves exactly this.
Seam is a superset of JSF and introduces a new conversation scope for
beans that does exactly what you want.
Seam supports richfaces natively (both are projects of JBoss/Redhat) so
you should not expect any problems with integration.
What is the reason the bean needs to be in session scope ?
If this is only to get ajax functionality then you can change the bean to request and use the a4j:keepAlive tag.
a4j:keepAlive extends the live cycle for the request scope bean, your bean instance then acts like it is in session scope for ajax requests. When the user opens two of the same page they are using two different bean instances.

Resources