Is it possible to have a JSF managed bean be automatically created?
For example I have several session scoped beans. Sometimes it becomes necessary to access these instances in code (rather than just in JSF) this is done by:
PageBean pageBean = (PageBean) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("pages");
However if no page has already been visited which calls to '#{pages}' this resolves to null ... is there anyway to get JSF to create a bean when the scope 'begins'? So in this case ideally when a user session begins the 'pages' bean would be instantiated in the session immediately?
Managed Bean is a regular Java Bean class registered with JSF. In other words, Managed Beans is a Java bean managed by JSF framework. Managed bean contains the getter and setter methods, business logic, or even a backing bean (a bean contains all the HTML form value). Managed beans works as Model for UI component.
In JSF, backing beans are JavaBeans used mainly to provide UI logic and to manage data between the web tier and the business tier of the application (similar to a data transfer object). Typically you have one backing bean per JSF page.
The managed-bean-class element defines the fully qualified name of the JavaBeans component class used to instantiate the bean. It is the application developer's responsibility to ensure that the class complies with the configuration of the bean in the application configuration resource file.
You can use following scopes for a bean class: Application (@ApplicationScoped): Application scope persists across all users? interactions with a web application. Session (@SessionScoped): Session scope persists across multiple HTTP requests in a web application.
Use Application#evaluateExpressionGet()
instead. It will create bean when not done yet.
FacesContext context = FacesContext.getCurrentInstance();
Bean bean = (Bean) context.getApplication().evaluateExpressionGet(context, "#{bean}", Bean.class);
Where "bean"
is the managed bean name and Bean.class
is the appropriate backing bean class.
You can if necessary wrap this up in a helper method so that casting is unnecessary (the JSF boys didn't take benefit of generics and the Class
parameter in evaluateExpressionGet
):
public static <T> T findBean(String managedBeanName, Class<T> beanClass) {
FacesContext context = FacesContext.getCurrentInstance();
return beanClass.cast(context.getApplication().evaluateExpressionGet(context, "#{" + managedBeanName + "}", beanClass));
}
which can be used as:
Bean bean = findBean("bean", Bean.class);
Or without the type, but with a @SuppressWarnings
:
@SuppressWarnings("unchecked")
public static <T> T findBean(String managedBeanName) {
FacesContext context = FacesContext.getCurrentInstance();
return (T) context.getApplication().evaluateExpressionGet(context, "#{" + managedBeanName + "}", Object.class);
}
which can be used as:
Bean bean = findBean("bean");
Update: the above is by the way JSF 1.2 specific. Here's the way for JSF 1.1 or older, using the currently deprecated Application#createValueBinding()
:
FacesContext context = FacesContext.getCurrentInstance();
Bean bean = (Bean) context.getApplication().createValueBinding("#{bean}").getValue(context);
What about this solution:
public static Object getBean(String beanName)
{
Object returnObject = FacesContext.getCurrentInstance().getELContext().getELResolver().getValue(FacesContext.getCurrentInstance().getELContext(), null, beanName);
if (returnObject == null)
System.out.println("Bean with name " + beanName + " was not found. Check the faces-config.xml file if the given bean name is ok.");
return returnObject;
}
By this way you can even avoid the Bean.class parameter.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With