Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSF Managed Bean auto-create?

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?

like image 249
rat Avatar asked Jan 12 '10 16:01

rat


People also ask

What is JSF managed bean?

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.

What is backing bean in JSF?

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.

Why do we need to define a managed bean?

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.

What scopes are available for a managed bean?

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.


2 Answers

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);
like image 122
BalusC Avatar answered Nov 08 '22 17:11

BalusC


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.

like image 33
Vic Avatar answered Nov 08 '22 15:11

Vic