JSF session scope beans with Tabbed browsing - jsf

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.

Related

Does JSF manage access authorization for #ManagedBean methods?

I have a #ManagedBean #SessionScoped class to represent a user session. Assume it has a theoretical method doHorribleThings(). Access to methods of this bean through JSF can, for example, be enabled through Expression Language attributes such as action="#{userSession.doHorribleThings()}" on a Prime Faces p:commandButton.
My question is, does JSF manage access security for such method? Can a user issue performing the action of a button that is not being rendered for him, e.g. by sending an artificial HTTP package? Or does JSF capsulate a virtual client desktop that stretches accross the network, effectively enabling access control through GUI design?
No, JSF doesn't have an access security for invoking a method in a managedbean other than the UI, as far as I know.
Because if your able to mimic an action that happens through the click of a JSP/Primefaces button with a manual HTTP request then JSF container cannot identify the difference between the two and hence work the same way for both the request

Using the correct JSF scope

While implementing a JSF based frontend I'm facing the following requirements:
The user can enter statements into a textfield.
The statements are forwarded to a server side EJB (in the same VM). The EJB stores information about each statement in collections (not in a DB) and use them while processing further statements.
After a statement has been processed its result is displayed on the same page.
The user can repeat this process several times. All the already processed statements must be displayed on the page.
Several users can access the application in parallel. Theoretically the same user can open multiple tabs in his/her browser. In this case this user could enter different statements and the statements in different tabs should be processed independently.
The problem:
The ViewScoped backing beans are recreated when the user sends a new statement to the server. A new backing bean instance gets another EJB reference if I declare it as #EJB private Service service;. Anyway, whatever I do I think I should expect that the ViewScoped beans will be recreated while the user is using the application.
Questions:
Which JSF scoped backing beans should I use: ViewScoped or SessionScoped?
Which session beans should I use as EJBs: Stateful or Stateless?
How should the EJBs be referenced in the backing beans?
I'm using Primefaces 5 + WildFly (if that matters).
EDIT:
Entering the statement means: writing it into the textfield and pressing Enter.
UPDATE:
I have switched the backing beans to SessionScoped, started the application and entered a statement.
UPDATE 2:
The previous problem has been solved: currently I use one page + one backing bean (SessionScoped) + one EJB (Stateful) and they are working fine together. But my three questions above are still valid: I'm not sure if this configuration is the best.

Jsf: what bean scope for a two page master-detail?

In a jsf application I have a table with summarized data. If I'm interested in the details I can click on a row an see the details in another page.
If the managed bean of the 'master' page is ion view scope it is re-created every time I return back from the 'detail' page and I don't think it is a good idea if the user is supposed to check the details more times. I can solve putting the bean in sessions cope but this way the bean (and the data) are kept in memory also when the user is interacting with the application in a completely different section. Probably I would need a custom scope but:
the documentation about custom scope is poor and I'm a bit frightened about people complaining it has bugs and doesn't work well.
the scenario I'm dealing with seems to me quite general, so I wonder why there is no ready solution for it.
Thanks
Filippo
If the detail page has to be idempotent (i.e. it's permalinkable, bookmarkable, searchbot-crawlable), just use two request or view scoped beans and use a GET link with the entity ID as request parameter to go from master page to detail page. See also Creating master-detail pages for entities, how to link them and which bean scope to choose for a concrete example.
If the detail page does not need to be idempotent, then you can always conditionally render the master and detail in the very same view or even display the detail in some modal dialog from the master page on. This way you can continue with a single view scoped bean.
In JSF side you must not be too much worried about the DB performance cost. Rather configure and finetune it in the persistence layer. In JPA for example you can setup a second level cache. If you've much more than 500~1000 items, then consider database-level pagination.
It may be valid to reload the master page each time e.g. if the data could have changed after viewing the details page. However, if you want to keep the data available for longer than #ViewScoped your options are:
You should be using JEE6 of which JSF 2.0 is a part of, so look at Conversation Scope (part of CDI)
Some additional scopes for JEE6 CDI is available through the MyFaces CODI
Potentially use Session Scope and make sure you tidy up when a Request hits which is not for the Master or Details page
Rework your design to use Ajax, so if clicking a record on the Master page its details load in the same view. You could then use #ViewScoped
My preference would be to look at the Conversation Scope. You don't mention which JSF implementation you are running or in which environment.

To handle Window.open in request Scope in jsf

I am using JSF 1.2 here i have a managed bean in request scope, my scenario is to open a seperate window. After action is performed oncomplete i am opening a new window since the managed bean in request scopes the values are not populated in new window. Because new object is being created while opening a new window. i can use session scope but that is restricted.
kindly help me in resolving this.
Two options:
use <rich:modalPanel> instead of a new window. Actually, window.open(..) should be even more restricted than session-scope (pop-up blockers would not allow the window to open)
use a conversation scope. MyFaces Orchestra provides such scope.
how about using a4j:keepalive to keep the request scope bean alive in the new page.
however for this to work i think your bean must implement Serializable interface.

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.

Resources