Problem
How can a JSF event listener class access another managed bean? See scenario below :
JSF page…
<h:selectOneMenu value="#{country.localeCode}" onchange="submit()">
<f:valueChangeListener type="com.mkyong.CountryValueListener" />
<f:selectItems value="#{country.countryInMap}" />
</h:selectOneMenu>
country managed bean…
package com.mkyong;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
@ManagedBean(name="country")
@SessionScoped
public class CountryBean implements Serializable{
private String localeCode;
public void setLocaleCode(String localeCode) {
this.localeCode = localeCode;
}
//...
}
ValueChangeListener…
package com.mkyong;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ValueChangeEvent;
import javax.faces.event.ValueChangeListener;
public class CountryValueListener implements ValueChangeListener{
@Override
public void processValueChange(ValueChangeEvent event)
throws AbortProcessingException {
//how to access the existing country managed bean?
//country.setLocaleCode(event.getNewValue().toString());
}
}
Solution
Actually, there are many ways to access an existing managed bean from an event listener class or another managed bean. See examples :
1. getApplicationMap()
If country managed bean is declared in application scope.
CountryBean country = (CountryBean) FacesContext.getCurrentInstance().
getExternalContext().getApplicationMap().get("country");
2. getRequestMap()
If country managed bean is declared in request scope.
CountryBean country = (CountryBean) FacesContext.getCurrentInstance().
getExternalContext().getRequestMap().get("country");
3. getSessionMap()
If country managed bean is declared in session scope.
CountryBean country = (CountryBean) FacesContext.getCurrentInstance().
getExternalContext().getSessionMap().get("country");
4. ELResolver()
Using ELResolver.
FacesContext context = FacesContext.getCurrentInstance();
CountryBean country = (CountryBean) context.
getELContext().getELResolver().getValue(context.getELContext(), null,"country");
5. ValueExpression()
Using ValueExpression.
FacesContext context = FacesContext.getCurrentInstance();
CountryBean country = (CountryBean) context.getApplication().getExpressionFactory()
.createValueExpression(context.getELContext(), "#{country}", CountryBean.class)
.getValue(context.getELContext());
6. evaluateExpressionGet()
Using evaluateExpressionGet.
FacesContext context = FacesContext.getCurrentInstance();
CountryBean country = (CountryBean)context.getApplication()
.evaluateExpressionGet(context, "#{country}", CountryBean.class);
very good post thanks but little description about these different ways will give more clarity.
How to get the view scoped and flash scoped bean from event listener ?
It helped me a lot in 2015, thanks! 🙂
Thank you.
Very useful and clear information . Thank you
Great article on JSF managed beans, thanks. I have a question, though: I need to access an application-scoped managed bean to modify certain properties from within an HttpSessionListener.
I already used something like the following:
@Override public void sessionDestroyed(HttpSessionEvent se) { HttpSession session = se.getSession(); User user = userService.findBySessionId(session.getId()); ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext(); ApplicationScopedBean appBean = (ApplicationScopedBean) externalContext.getApplicationMap().get("appBean"); appBean.getConnectedUsers().remove(user); }externalContext = FacesContext.getCurrentInstance().getExternalContext() causes a null pointer exception already, and even if it didn’t I’m not sure appBean could be accessible the above way.
Any ideas?