It is possible to access or to get a backing bean property value from another backing bean in JSF?
Yes, it is possible.
You can access another beans in the context by Application#evaluateExpressionGet(). You can also inject a bean as managed property of other bean in faces-config.xml. If you're already on JSF2, you can even use #ManagedProperty annotation like follows:
#ManagedProperty(value="#{bean}")
private Bean bean;
Related
I have the following UserView class:
#ManagedBean(name="usersView", eager=true)
#ApplicationScoped
public class UserView
{
...
public void setUsers(...)
{
...
}
}
I then have another class, UserService which tries to access this bean and then call this method, as follows:
UserView usersView = (UserView) FacesContext.getCurrentInstance().getExternalContext().getSessionMap("usersView");
usersView.setUsers(...)
My issue is, is that usersView keeps coming back as null and hence the method cannot be called.
My end goal is to use this data in a PrimeFaces datatable, like so:
<p:dataTable var="user" value="#{usersView.users}" ...>
I have also tried changing the scope to SessionScoped, but it is still null and I cannot figure out why.
Any suggestions would be greatly appreciated.
The getExternalContext().getXxxMap().get("beanName") approach won't autocreate beans if they don't exist yet. Managed beans will only be autocreated when an EL expression referencing the bean is evaluated. Accessing the scope map doesn't do that. For that, use #ManagedProperty in the source bean instead. You can specify an EL expression in its value.
#ManagedProperty("#{userView}")
private UserView userView; // +setter (no getter required).
Note that this only works if the source bean has the same or a narrower scope than the target bean. If that's not the case, consider managing beans using CDI instead of JSF. You can then use #Inject instead of #ManagedProperty (which doesn't require a setter by the way). Moreover, #ManagedBean and friends is deprecated in upcoming JSF 2.3.
As to eager=true, this has only effect on #ApplicationScoped beans. See also the javadoc (emphasis mine).
...
If the value of the eager() attribute is true, and the managed-bean-scope value is "application", the runtime must instantiate this class when the application starts. This instantiation and storing of the instance must happen before any requests are serviced. If eager is unspecified or false, or the managed-bean-scope is something other than "application", the default "lazy" instantiation and scoped storage of the managed bean happens.
...
See also:
How to choose the right bean scope?
Difference between #ManagedProperty and FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("bean")
Get JSF managed bean by name in any Servlet related class
Backing beans (#ManagedBean) or CDI Beans (#Named)?
I have a requestscoped bean which can receive its data from three different viewscoped beans (from 3 different pages). The beans are JSF Managed Beans.
When I use ManagedProperty in the request scoped for 3 different view scoped beans, it instantiates the view scoped beans which is what I do NOT want. I want to simply know from which bean it is being called from and then call a specific method (different) for each bean.
How can I check which bean is instantiated and in scope so I can call the correct bean's method?
Looks like it's pretty simple. I was reading one of Balus's posts. I simply used ManagedProperty(value="#{viewScope.managedBeanName}") . It did not instantiate. For the inscope, it gave me the created bean :). Happy
I'm new to JSF and was wondering:
If I have a controller that handles all the work for a given page and a bean that holds all the data for said page, is It necessary to have both the
#ManagedProperty(value="#{myBean}")
annotation on the controller and the
#ManagedBean(name="myBean")
#SessionScoped
annotations on the form bean?
Managed beans in JSF are used to store the state of a web page. The JSF implementation is responsible for creating and discarding the bean objects( hence the name managed bean).
For every class you write #ManagedBean, the bean object is created by the JSF implementation as and when it detects an usage of the bean with the name(you can either sepcify a bean name or leave it to JSF to use the default name-class name with the first character changed to lowercase). The object created is placed in a map of the specified scope. Each scope has a map that it uses to store bean objects which have that scope specified.
Now if you need the values of these beans in your controller, you have to inject it using the ManagedProperty annotation. Note that you would need to provide the controller with a setter method for the managedProperty.
So to answer your question, the managedBean annotation is required to tell the JSF implementation to manage the bean instance and store the values in the table specific to the session scope. And the ManagedProperty annotation is needed to use that bean stored in the current session so that you can access all of its values.
We use #ManagedBean annotation to register a java bean with a JSF framework. This is a replacement for a faces-config.xml <managed-bean> element. We typically do not use name attribute because it already defaults to a simple class name camel cased.
We use #RequestScope and other scope annotations to explicitly specify the scope we want via annotation. This is equivalent to specifying<managed-bean-scope> xml entry. If you don't specify the scope it will be defaulted to #NoneScoped.
We use #ManagedProperty and specify an EL-expression in its value attribute to use JSF-provided dependency injection engine for JSF artifacts like other managed beans with broader scopes and EL-defined variables like param. We do it in case we need the injected values in other JSF artifacts, most typically beans. The injected values are available in bean's #PostConstruct-annotated method. This is an alternative to <managed-property> xml entry.
To sum it up. Use #ManagedBean #RequestScoped to register a bean with JSF framework. Use #ManagedProperty inside this bean to be able to reference among others other JSF beans with the same or broader scopes in this bean. In case you don't need to reference other beans in the created bean you don't need to use the #ManagedProperty annotation as it's purely optional.
I have a bean that does some logic, I call it logicBean,
and it has a sessionscoped bean as field with #Inject.
I use this logicbean in two situations in one JAVA EE6 Application,
1. in servlet.
2. in message driven bean.
In the second situcation, I got a excetion
"WebBeans context with scope type annotation #SessionScoped does not exist within current thread".
I know there is no sessionScope in MDB, so I made another bean, and want to
inject it to logicBean dynamicly to alternative the sessionScoped bean.
I do not know how to do this.
please help me, thanks.
This question already has answers here:
Get JSF managed bean by name in any Servlet related class
(6 answers)
Closed 2 years ago.
We are using the following code to get the managed bean instance from the context.
FacesUtils.getManagedBean("beanName");
Is it the correct way of doing it?. If multiple users access the same bean what will happen?
How the bean instances are managed?
Since FacesUtils is not part of standard JSF implementation, it's unclear what it is actually doing under the covers.
Regardless, when you're already inside a managed bean, then the preferred way is to inject the other bean as managed property. I'll assume that you're already on JSF 2.0, so here's a JSF 2.0 targeted example.
#ManagedBean
#SessionScoped
public void OtherBean {}
#ManagedBean
#RequestScoped
public void YourBean {
#ManagedProperty("#{otherBean}")
private void OtherBean;
#PostConstruct
public void init() {
otherBean.doSomething(); // OtherBean is now available in any method.
}
public void setOtherBean(OtherBean otherBean) {
this.otherBean = otherBean;
}
// Getter is not necessary.
}
But when you're still on JSF 1.x, then you need to do it by <managed-property> entry in faces-config.xml as explained in this question: Passing data between managed beans.
If you happen to use CDI #Named instead of JSF #ManagedBean, use #Inject instead of #ManagedProperty. For this, a setter method is not required.
See also:
Communication in JSF2
Get JSF managed bean by name in any Servlet related class
Backing beans (#ManagedBean) or CDI Beans (#Named)?
As to your concern
If multiple users access the same bean what will happen? How the bean instances are managed?
They are managed by JSF. If a bean is found, then JSF will just return exactly this bean. If no bean is found, then JSF will just auto-create one and put in the associated scope. JSF won't unnecessarily create multiple beans.