Using the correct JSF scope - jsf

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.

Related

How can I increment the Counter and Score values of Dice game with JSF [duplicate]

I noticed that there are different bean scopes like:
#RequestScoped
#ViewScoped
#FlowScoped
#SessionScoped
#ApplicationScoped
What is the purpose of each? How do I choose a proper scope for my bean?
Introduction
It represents the scope (the lifetime) of the bean. This is easier to understand if you are familiar with "under the covers" working of a basic servlet web application: How do servlets work? Instantiation, sessions, shared variables and multithreading.
#Request/View/Flow/Session/ApplicationScoped
A #RequestScoped bean lives as long as a single HTTP request-response cycle (note that an Ajax request counts as a single HTTP request too). A #ViewScoped bean lives as long as you're interacting with the same JSF view by postbacks which call action methods returning null/void without any navigation/redirect. A #FlowScoped bean lives as long as you're navigating through the specified collection of views registered in the flow configuration file. A #SessionScoped bean lives as long as the established HTTP session. An #ApplicationScoped bean lives as long as the web application runs. Note that the CDI #Model is basically a stereotype for #Named #RequestScoped, so same rules apply.
Which scope to choose depends solely on the data (the state) the bean holds and represents. Use #RequestScoped for simple and non-ajax forms/presentations. Use #ViewScoped for rich ajax-enabled dynamic views (ajaxbased validation, rendering, dialogs, etc). Use #FlowScoped for the "wizard" ("questionnaire") pattern of collecting input data spread over multiple pages. Use #SessionScoped for client specific data, such as the logged-in user and user preferences (language, etc). Use #ApplicationScoped for application wide data/constants, such as dropdown lists which are the same for everyone, or managed beans without any instance variables and having only methods.
Abusing an #ApplicationScoped bean for session/view/request scoped data would make it to be shared among all users, so anyone else can see each other's data which is just plain wrong. Abusing a #SessionScoped bean for view/request scoped data would make it to be shared among all tabs/windows in a single browser session, so the enduser may experience inconsitenties when interacting with every view after switching between tabs which is bad for user experience. Abusing a #RequestScoped bean for view scoped data would make view scoped data to be reinitialized to default on every single (ajax) postback, causing possibly non-working forms (see also points 4 and 5 here). Abusing a #ViewScoped bean for request, session or application scoped data, and abusing a #SessionScoped bean for application scoped data doesn't affect the client, but it unnecessarily occupies server memory and is plain inefficient.
Note that the scope should rather not be chosen based on performance implications, unless you really have a low memory footprint and want to go completely stateless; you'd need to use exclusively #RequestScoped beans and fiddle with request parameters to maintain the client's state. Also note that when you have a single JSF page with differently scoped data, then it's perfectly valid to put them in separate backing beans in a scope matching the data's scope. The beans can just access each other via #ManagedProperty in case of JSF managed beans or #Inject in case of CDI managed beans.
See also:
Difference between View and Request scope in managed beans
Advantages of using JSF Faces Flow instead of the normal navigation system
Communication in JSF2 - Managed bean scopes
#CustomScoped/NoneScoped/Dependent
It's not mentioned in your question, but (legacy) JSF also supports #CustomScoped and #NoneScoped, which are rarely used in real world. The #CustomScoped must refer a custom Map<K, Bean> implementation in some broader scope which has overridden Map#put() and/or Map#get() in order to have more fine grained control over bean creation and/or destroy.
The JSF #NoneScoped and CDI #Dependent basically lives as long as a single EL-evaluation on the bean. Imagine a login form with two input fields referring a bean property and a command button referring a bean action, thus with in total three EL expressions, then effectively three instances will be created. One with the username set, one with the password set and one on which the action is invoked. You normally want to use this scope only on beans which should live as long as the bean where it's being injected. So if a #NoneScoped or #Dependent is injected in a #SessionScoped, then it will live as long as the #SessionScoped bean.
See also:
Expire specific managed bean instance after time interval
what is none scope bean and when to use it?
What is the default Managed Bean Scope in a JSF 2 application?
Flash scope
As last, JSF also supports the flash scope. It is backed by a short living cookie which is associated with a data entry in the session scope. Before the redirect, a cookie will be set on the HTTP response with a value which is uniquely associated with the data entry in the session scope. After the redirect, the presence of the flash scope cookie will be checked and the data entry associated with the cookie will be removed from the session scope and be put in the request scope of the redirected request. Finally the cookie will be removed from the HTTP response. This way the redirected request has access to request scoped data which was been prepared in the initial request.
This is actually not available as a managed bean scope, i.e. there's no such thing as #FlashScoped. The flash scope is only available as a map via ExternalContext#getFlash() in managed beans and #{flash} in EL.
See also:
How to show faces message in the redirected page
Pass an object between #ViewScoped beans without using GET params
CDI missing #ViewScoped and #FlashScoped
Since JSF 2.3 all the bean scopes defined in package javax.faces.bean package have been deprecated to align the scopes with CDI. Moreover they're only applicable if your bean is using #ManagedBean annotation. If you are using JSF versions below 2.3 refer to the legacy answer at the end.
From JSF 2.3 here are scopes that can be used on JSF Backing Beans:
1. #javax.enterprise.context.ApplicationScoped: The application scope persists for the entire duration of the web application. That scope is shared among all requests and all sessions. This is useful when you have data for whole application.
2. #javax.enterprise.context.SessionScoped: The session scope persists from the time that a session is established until session termination. The session context is shared between all requests that occur in the same HTTP session. This is useful when you wont to save data for a specific client for a particular session.
3. #javax.enterprise.context.ConversationScoped: The conversation scope persists as log as the bean lives. The scope provides 2 methods: Conversation.begin() and Conversation.end(). These methods should called explicitly, either to start or end the life of a bean.
4. #javax.enterprise.context.RequestScoped: The request scope is short-lived. It starts when an HTTP request is submitted and ends after the response is sent back to the client. If you place a managed bean into request scope, a new instance is created with each request. It is worth considering request scope if you are concerned about the cost of session scope storage.
5. #javax.faces.flow.FlowScoped: The Flow scope persists as long as the Flow lives. A flow may be defined as a contained set of pages (or views) that define a unit of work. Flow scoped been is active as long as user navigates with in the Flow.
6. #javax.faces.view.ViewScoped: A bean in view scope persists while the same JSF page is redisplayed. As soon as the user navigates to a different page, the bean goes out of scope.
The following legacy answer applies JSF version before 2.3
As of JSF 2.x there are 4 Bean Scopes:
#SessionScoped
#RequestScoped
#ApplicationScoped
#ViewScoped
Session Scope: The session scope persists from the time that a session is established until session termination. A session terminates
if the web application invokes the invalidate method on the
HttpSession object, or if it times out.
RequestScope: The request scope is short-lived. It starts when an HTTP request is submitted and ends after the response is sent back
to the client. If you place a managed bean into request scope, a new
instance is created with each request. It is worth considering request
scope if you are concerned about the cost of session scope storage.
ApplicationScope: The application scope persists for the entire duration of the web application. That scope is shared among all
requests and all sessions. You place managed beans into the
application scope if a single bean should be shared among all
instances of a web application. The bean is constructed when it is
first requested by any user of the application, and it stays alive
until the web application is removed from the application server.
ViewScope: View scope was added in JSF 2.0. A bean in view scope persists while the same JSF page is redisplayed. (The JSF
specification uses the term view for a JSF page.) As soon as the user
navigates to a different page, the bean goes out of scope.
Choose the scope you based on your requirement.
Source: Core Java Server Faces 3rd Edition by David Geary & Cay Horstmann [Page no. 51 - 54]

Java JSF and CDI, referencing to the same #Model from different backing beans [duplicate]

I noticed that there are different bean scopes like:
#RequestScoped
#ViewScoped
#FlowScoped
#SessionScoped
#ApplicationScoped
What is the purpose of each? How do I choose a proper scope for my bean?
Introduction
It represents the scope (the lifetime) of the bean. This is easier to understand if you are familiar with "under the covers" working of a basic servlet web application: How do servlets work? Instantiation, sessions, shared variables and multithreading.
#Request/View/Flow/Session/ApplicationScoped
A #RequestScoped bean lives as long as a single HTTP request-response cycle (note that an Ajax request counts as a single HTTP request too). A #ViewScoped bean lives as long as you're interacting with the same JSF view by postbacks which call action methods returning null/void without any navigation/redirect. A #FlowScoped bean lives as long as you're navigating through the specified collection of views registered in the flow configuration file. A #SessionScoped bean lives as long as the established HTTP session. An #ApplicationScoped bean lives as long as the web application runs. Note that the CDI #Model is basically a stereotype for #Named #RequestScoped, so same rules apply.
Which scope to choose depends solely on the data (the state) the bean holds and represents. Use #RequestScoped for simple and non-ajax forms/presentations. Use #ViewScoped for rich ajax-enabled dynamic views (ajaxbased validation, rendering, dialogs, etc). Use #FlowScoped for the "wizard" ("questionnaire") pattern of collecting input data spread over multiple pages. Use #SessionScoped for client specific data, such as the logged-in user and user preferences (language, etc). Use #ApplicationScoped for application wide data/constants, such as dropdown lists which are the same for everyone, or managed beans without any instance variables and having only methods.
Abusing an #ApplicationScoped bean for session/view/request scoped data would make it to be shared among all users, so anyone else can see each other's data which is just plain wrong. Abusing a #SessionScoped bean for view/request scoped data would make it to be shared among all tabs/windows in a single browser session, so the enduser may experience inconsitenties when interacting with every view after switching between tabs which is bad for user experience. Abusing a #RequestScoped bean for view scoped data would make view scoped data to be reinitialized to default on every single (ajax) postback, causing possibly non-working forms (see also points 4 and 5 here). Abusing a #ViewScoped bean for request, session or application scoped data, and abusing a #SessionScoped bean for application scoped data doesn't affect the client, but it unnecessarily occupies server memory and is plain inefficient.
Note that the scope should rather not be chosen based on performance implications, unless you really have a low memory footprint and want to go completely stateless; you'd need to use exclusively #RequestScoped beans and fiddle with request parameters to maintain the client's state. Also note that when you have a single JSF page with differently scoped data, then it's perfectly valid to put them in separate backing beans in a scope matching the data's scope. The beans can just access each other via #ManagedProperty in case of JSF managed beans or #Inject in case of CDI managed beans.
See also:
Difference between View and Request scope in managed beans
Advantages of using JSF Faces Flow instead of the normal navigation system
Communication in JSF2 - Managed bean scopes
#CustomScoped/NoneScoped/Dependent
It's not mentioned in your question, but (legacy) JSF also supports #CustomScoped and #NoneScoped, which are rarely used in real world. The #CustomScoped must refer a custom Map<K, Bean> implementation in some broader scope which has overridden Map#put() and/or Map#get() in order to have more fine grained control over bean creation and/or destroy.
The JSF #NoneScoped and CDI #Dependent basically lives as long as a single EL-evaluation on the bean. Imagine a login form with two input fields referring a bean property and a command button referring a bean action, thus with in total three EL expressions, then effectively three instances will be created. One with the username set, one with the password set and one on which the action is invoked. You normally want to use this scope only on beans which should live as long as the bean where it's being injected. So if a #NoneScoped or #Dependent is injected in a #SessionScoped, then it will live as long as the #SessionScoped bean.
See also:
Expire specific managed bean instance after time interval
what is none scope bean and when to use it?
What is the default Managed Bean Scope in a JSF 2 application?
Flash scope
As last, JSF also supports the flash scope. It is backed by a short living cookie which is associated with a data entry in the session scope. Before the redirect, a cookie will be set on the HTTP response with a value which is uniquely associated with the data entry in the session scope. After the redirect, the presence of the flash scope cookie will be checked and the data entry associated with the cookie will be removed from the session scope and be put in the request scope of the redirected request. Finally the cookie will be removed from the HTTP response. This way the redirected request has access to request scoped data which was been prepared in the initial request.
This is actually not available as a managed bean scope, i.e. there's no such thing as #FlashScoped. The flash scope is only available as a map via ExternalContext#getFlash() in managed beans and #{flash} in EL.
See also:
How to show faces message in the redirected page
Pass an object between #ViewScoped beans without using GET params
CDI missing #ViewScoped and #FlashScoped
Since JSF 2.3 all the bean scopes defined in package javax.faces.bean package have been deprecated to align the scopes with CDI. Moreover they're only applicable if your bean is using #ManagedBean annotation. If you are using JSF versions below 2.3 refer to the legacy answer at the end.
From JSF 2.3 here are scopes that can be used on JSF Backing Beans:
1. #javax.enterprise.context.ApplicationScoped: The application scope persists for the entire duration of the web application. That scope is shared among all requests and all sessions. This is useful when you have data for whole application.
2. #javax.enterprise.context.SessionScoped: The session scope persists from the time that a session is established until session termination. The session context is shared between all requests that occur in the same HTTP session. This is useful when you wont to save data for a specific client for a particular session.
3. #javax.enterprise.context.ConversationScoped: The conversation scope persists as log as the bean lives. The scope provides 2 methods: Conversation.begin() and Conversation.end(). These methods should called explicitly, either to start or end the life of a bean.
4. #javax.enterprise.context.RequestScoped: The request scope is short-lived. It starts when an HTTP request is submitted and ends after the response is sent back to the client. If you place a managed bean into request scope, a new instance is created with each request. It is worth considering request scope if you are concerned about the cost of session scope storage.
5. #javax.faces.flow.FlowScoped: The Flow scope persists as long as the Flow lives. A flow may be defined as a contained set of pages (or views) that define a unit of work. Flow scoped been is active as long as user navigates with in the Flow.
6. #javax.faces.view.ViewScoped: A bean in view scope persists while the same JSF page is redisplayed. As soon as the user navigates to a different page, the bean goes out of scope.
The following legacy answer applies JSF version before 2.3
As of JSF 2.x there are 4 Bean Scopes:
#SessionScoped
#RequestScoped
#ApplicationScoped
#ViewScoped
Session Scope: The session scope persists from the time that a session is established until session termination. A session terminates
if the web application invokes the invalidate method on the
HttpSession object, or if it times out.
RequestScope: The request scope is short-lived. It starts when an HTTP request is submitted and ends after the response is sent back
to the client. If you place a managed bean into request scope, a new
instance is created with each request. It is worth considering request
scope if you are concerned about the cost of session scope storage.
ApplicationScope: The application scope persists for the entire duration of the web application. That scope is shared among all
requests and all sessions. You place managed beans into the
application scope if a single bean should be shared among all
instances of a web application. The bean is constructed when it is
first requested by any user of the application, and it stays alive
until the web application is removed from the application server.
ViewScope: View scope was added in JSF 2.0. A bean in view scope persists while the same JSF page is redisplayed. (The JSF
specification uses the term view for a JSF page.) As soon as the user
navigates to a different page, the bean goes out of scope.
Choose the scope you based on your requirement.
Source: Core Java Server Faces 3rd Edition by David Geary & Cay Horstmann [Page no. 51 - 54]

Right way to organize scopes for JSF [duplicate]

I noticed that there are different bean scopes like:
#RequestScoped
#ViewScoped
#FlowScoped
#SessionScoped
#ApplicationScoped
What is the purpose of each? How do I choose a proper scope for my bean?
Introduction
It represents the scope (the lifetime) of the bean. This is easier to understand if you are familiar with "under the covers" working of a basic servlet web application: How do servlets work? Instantiation, sessions, shared variables and multithreading.
#Request/View/Flow/Session/ApplicationScoped
A #RequestScoped bean lives as long as a single HTTP request-response cycle (note that an Ajax request counts as a single HTTP request too). A #ViewScoped bean lives as long as you're interacting with the same JSF view by postbacks which call action methods returning null/void without any navigation/redirect. A #FlowScoped bean lives as long as you're navigating through the specified collection of views registered in the flow configuration file. A #SessionScoped bean lives as long as the established HTTP session. An #ApplicationScoped bean lives as long as the web application runs. Note that the CDI #Model is basically a stereotype for #Named #RequestScoped, so same rules apply.
Which scope to choose depends solely on the data (the state) the bean holds and represents. Use #RequestScoped for simple and non-ajax forms/presentations. Use #ViewScoped for rich ajax-enabled dynamic views (ajaxbased validation, rendering, dialogs, etc). Use #FlowScoped for the "wizard" ("questionnaire") pattern of collecting input data spread over multiple pages. Use #SessionScoped for client specific data, such as the logged-in user and user preferences (language, etc). Use #ApplicationScoped for application wide data/constants, such as dropdown lists which are the same for everyone, or managed beans without any instance variables and having only methods.
Abusing an #ApplicationScoped bean for session/view/request scoped data would make it to be shared among all users, so anyone else can see each other's data which is just plain wrong. Abusing a #SessionScoped bean for view/request scoped data would make it to be shared among all tabs/windows in a single browser session, so the enduser may experience inconsitenties when interacting with every view after switching between tabs which is bad for user experience. Abusing a #RequestScoped bean for view scoped data would make view scoped data to be reinitialized to default on every single (ajax) postback, causing possibly non-working forms (see also points 4 and 5 here). Abusing a #ViewScoped bean for request, session or application scoped data, and abusing a #SessionScoped bean for application scoped data doesn't affect the client, but it unnecessarily occupies server memory and is plain inefficient.
Note that the scope should rather not be chosen based on performance implications, unless you really have a low memory footprint and want to go completely stateless; you'd need to use exclusively #RequestScoped beans and fiddle with request parameters to maintain the client's state. Also note that when you have a single JSF page with differently scoped data, then it's perfectly valid to put them in separate backing beans in a scope matching the data's scope. The beans can just access each other via #ManagedProperty in case of JSF managed beans or #Inject in case of CDI managed beans.
See also:
Difference between View and Request scope in managed beans
Advantages of using JSF Faces Flow instead of the normal navigation system
Communication in JSF2 - Managed bean scopes
#CustomScoped/NoneScoped/Dependent
It's not mentioned in your question, but (legacy) JSF also supports #CustomScoped and #NoneScoped, which are rarely used in real world. The #CustomScoped must refer a custom Map<K, Bean> implementation in some broader scope which has overridden Map#put() and/or Map#get() in order to have more fine grained control over bean creation and/or destroy.
The JSF #NoneScoped and CDI #Dependent basically lives as long as a single EL-evaluation on the bean. Imagine a login form with two input fields referring a bean property and a command button referring a bean action, thus with in total three EL expressions, then effectively three instances will be created. One with the username set, one with the password set and one on which the action is invoked. You normally want to use this scope only on beans which should live as long as the bean where it's being injected. So if a #NoneScoped or #Dependent is injected in a #SessionScoped, then it will live as long as the #SessionScoped bean.
See also:
Expire specific managed bean instance after time interval
what is none scope bean and when to use it?
What is the default Managed Bean Scope in a JSF 2 application?
Flash scope
As last, JSF also supports the flash scope. It is backed by a short living cookie which is associated with a data entry in the session scope. Before the redirect, a cookie will be set on the HTTP response with a value which is uniquely associated with the data entry in the session scope. After the redirect, the presence of the flash scope cookie will be checked and the data entry associated with the cookie will be removed from the session scope and be put in the request scope of the redirected request. Finally the cookie will be removed from the HTTP response. This way the redirected request has access to request scoped data which was been prepared in the initial request.
This is actually not available as a managed bean scope, i.e. there's no such thing as #FlashScoped. The flash scope is only available as a map via ExternalContext#getFlash() in managed beans and #{flash} in EL.
See also:
How to show faces message in the redirected page
Pass an object between #ViewScoped beans without using GET params
CDI missing #ViewScoped and #FlashScoped
Since JSF 2.3 all the bean scopes defined in package javax.faces.bean package have been deprecated to align the scopes with CDI. Moreover they're only applicable if your bean is using #ManagedBean annotation. If you are using JSF versions below 2.3 refer to the legacy answer at the end.
From JSF 2.3 here are scopes that can be used on JSF Backing Beans:
1. #javax.enterprise.context.ApplicationScoped: The application scope persists for the entire duration of the web application. That scope is shared among all requests and all sessions. This is useful when you have data for whole application.
2. #javax.enterprise.context.SessionScoped: The session scope persists from the time that a session is established until session termination. The session context is shared between all requests that occur in the same HTTP session. This is useful when you wont to save data for a specific client for a particular session.
3. #javax.enterprise.context.ConversationScoped: The conversation scope persists as log as the bean lives. The scope provides 2 methods: Conversation.begin() and Conversation.end(). These methods should called explicitly, either to start or end the life of a bean.
4. #javax.enterprise.context.RequestScoped: The request scope is short-lived. It starts when an HTTP request is submitted and ends after the response is sent back to the client. If you place a managed bean into request scope, a new instance is created with each request. It is worth considering request scope if you are concerned about the cost of session scope storage.
5. #javax.faces.flow.FlowScoped: The Flow scope persists as long as the Flow lives. A flow may be defined as a contained set of pages (or views) that define a unit of work. Flow scoped been is active as long as user navigates with in the Flow.
6. #javax.faces.view.ViewScoped: A bean in view scope persists while the same JSF page is redisplayed. As soon as the user navigates to a different page, the bean goes out of scope.
The following legacy answer applies JSF version before 2.3
As of JSF 2.x there are 4 Bean Scopes:
#SessionScoped
#RequestScoped
#ApplicationScoped
#ViewScoped
Session Scope: The session scope persists from the time that a session is established until session termination. A session terminates
if the web application invokes the invalidate method on the
HttpSession object, or if it times out.
RequestScope: The request scope is short-lived. It starts when an HTTP request is submitted and ends after the response is sent back
to the client. If you place a managed bean into request scope, a new
instance is created with each request. It is worth considering request
scope if you are concerned about the cost of session scope storage.
ApplicationScope: The application scope persists for the entire duration of the web application. That scope is shared among all
requests and all sessions. You place managed beans into the
application scope if a single bean should be shared among all
instances of a web application. The bean is constructed when it is
first requested by any user of the application, and it stays alive
until the web application is removed from the application server.
ViewScope: View scope was added in JSF 2.0. A bean in view scope persists while the same JSF page is redisplayed. (The JSF
specification uses the term view for a JSF page.) As soon as the user
navigates to a different page, the bean goes out of scope.
Choose the scope you based on your requirement.
Source: Core Java Server Faces 3rd Edition by David Geary & Cay Horstmann [Page no. 51 - 54]

Spring security and JSF: call method on backing bean on login?

I want a method in a session scoped backing bean to be called after a user logs in. How can I do that?
Environment: Spring Security 3.0.x, Spring 3.0.x and JSF 1.2. The backing beans are managed by Spring.
Background: Sessions are created even without login. My session scoped bean holds settings, that are initially set to default values. After login I want to update the session state to the preferences stored in the database for that particular user. To achieve that I imagined an interface or even simpler an annotated (e.g. #PostLogin) method, but so far I have not found anything like that.
It would be OK if that method is called on every principal change, i.e. also on logout. It would also be acceptable if the whole bean is destructed and recreated on login, though my other session scoped beans should survive.
What I have found so far is:
ApplicationListener<AuthenticationSuccessEvent>: The listener apparently needs to be application scoped, and I can't get access to my session scoped bean in it. #Autowired plus scope proxy don't work. The injected object is broken; it does not contain its dependencies although the real backing bean does.
<form-login authentication-success-handler-ref="..">: haven't tried this, but I need the method to be called independent of the used login procedure. Other than form based we support remember me and programmatic login (e.g. automatically logged in after password forgotten process).
Answering my own question:
ApplicationListener was the right track, however #Autowired was not.
I defined an interface with one method, that is implemented by my session scoped bean. The (singleton scoped) event listener class then uses ApplicationContext.getBeansOfType(..) to find the session beans by that interface and invokes the interface's method on each of them.

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