Access a managed bean from event listener – JSF

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);

Reference

  1. getApplicationMap() java Doc
  2. getRequestMap() JavaDoc
  3. getSessionMap() JavaDoc
  4. getELResolver() JavaDoc
  5. createValueExpression() JavaDoc
  6. evaluateExpressionGet() JavaDoc

6 comments on “Access a managed bean from event listener – JSF

  1. very good post thanks but little description about these different ways will give more clarity.

    Reply
  2. How to get the view scoped and flash scoped bean from event listener ?

    Reply
  3. 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?

    Reply

Leave a Comment

Your email address will not be published. Required fields are marked *