5 useful methods JSF developers should know

The aim of this post is a summary about some handy methods for JSF developers they can use in their day-to-day work. An utility class is a good place to put all methods together. I would call such class FacesAccessor. The first method is probably the most used one. It returns managed bean by the given name.

The bean must be registered either per faces-config.xml or annotation. Injection is good, but sometimes if beans are rare called, it’s not necessary to inject beans into each other.
 
 
 

public static Object getManagedBean(final String beanName) {
    FacesContext fc = FacesContext.getCurrentInstance();
    Object bean;
    
    try {
        ELContext elContext = fc.getELContext();
        bean = elContext.getELResolver().getValue(elContext, null, beanName);
    } catch (RuntimeException e) {
        throw new FacesException(e.getMessage(), e);
    }

    if (bean == null) {
        throw new FacesException("Managed bean with name '" + beanName
            + "' was not found. Check your faces-config.xml or @ManagedBean annotation.");
    }

    return bean;
}

Using:

@ManagedBean
public class PersonBean {
    ...
}

PersonBean personBean = (PersonBean)FacesAccessor.getManagedBean("personBean");

// do something with personBean

The second method is useful for JSF component developers and everyone who would like to evaluate the given value expression #{…} and sets the result to the given value.

public static void setValue2ValueExpression(final Object value, final String expression) {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    ELContext elContext = facesContext.getELContext();

    ValueExpression targetExpression = 
        facesContext.getApplication().getExpressionFactory().createValueExpression(elContext, expression, Object.class);
    targetExpression.setValue(elContext, value);
}

Using: 
I personally use this method for the “log off functionality”. After an user is logged off, he/she will see a special “logoff page”. The “logoff page” uses user settings (e.g. theme, language, etc.) from a sesion scoped bean. But this session scoped bean doesn’t exist more because the session was invalidated. What to do? Here is the code snippet from my logout method.

UserSettings userSettings = (UserSettings) FacesAccessor.getManagedBean("userSettings");

// invalidate session
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
HttpSession session = (HttpSession) ec.getSession(false);
session.invalidate();

// create new session
((HttpServletRequest) ec.getRequest()).getSession(true);

// restore last used user settings because login / logout pages reference "userSettings"
FacesAccessor.setValue2ValueExpression(userSettings, "#{userSettings}");

// redirect to the specified logout page
ec.redirect(ec.getRequestContextPath() + "/views/logout.jsf");

The third method maps a variable to the given value expression #{…}. It uses javax.el.VariableMapper to assign the expression to the specified variable, so that any reference to that variable will be replaced by the expression in EL evaluations.

public static void mapVariable2ValueExpression(final String variable, final String expression) {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    ELContext elContext = facesContext.getELContext();
    
    ValueExpression targetExpression =
        facesContext.getApplication().getExpressionFactory().createValueExpression(elContext, expression, Object.class);
    elContext.getVariableMapper().setVariable(variable, targetExpression);
}

Using: 
Assume, “PersonBean” is a managed bean having “name” attribute and “PersonsBean” is a bean holding many instances of “PersonBean” (as array, collection or map). The following code allows to use “personBean” as a reference to a specific bean with “name” Oleg.

FacesAccessor.mapVariable2ValueExpression("personBean", "#{personsBean.person['Oleg']}");

In a facelets page, say so, personDetail.xhtml, we can write:

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html">
<ui:composition>
    ...
    <h:inputText value="#{personBean.name}"/>
    ...
</ui:composition>
</html>

Note, the reference “personBean” was set in Java. This mapping can be also used in facelets in declarative way via ui:include / ui:param.

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets">
<ui:composition>
    ...
    <ui:include src="personDetail.xhtml">
        <ui:param name="personBean" value="#{personsBean.person['Oleg']}"/>
    </ui:include>
    ...
</ui:composition>
</html>

The next two methods are used to create MethodExpression / MethodExpressionActionListener programmatically. They are handy if you use component binding via “binding” attribute or create some model classes in Java.

public static MethodExpression createMethodExpression(String valueExpression,
                                                      Class<?> expectedReturnType,
                                                      Class<?>[] expectedParamTypes) {
    MethodExpression methodExpression = null;
    try {
        FacesContext fc = FacesContext.getCurrentInstance();
        ExpressionFactory factory = fc.getApplication().getExpressionFactory();
        methodExpression = factory.
            createMethodExpression(fc.getELContext(), valueExpression, expectedReturnType, expectedParamTypes);
    } catch (Exception e) {
        throw new FacesException("Method expression '" + valueExpression + "' could not be created.");
    }
    
    return methodExpression;
}

public static MethodExpressionActionListener createMethodActionListener(String valueExpression,
                                                                        Class<?> expectedReturnType,
                                                                        Class<?>[] expectedParamTypes) {
    MethodExpressionActionListener actionListener = null;
    try {
        actionListener = new MethodExpressionActionListener(createMethodExpression(
            valueExpression, expectedReturnType, expectedParamTypes));
    } catch (Exception e) {
        throw new FacesException("Method expression for ActionListener '" + valueExpression
                          + "' could not be created.");
    }

    return actionListener;
}

Using: 
In one of my projects I have created PrimeFaces MenuModel with menu items programmatically.

MenuItem mi = new MenuItem();
mi.setAjax(true);
mi.setValue(...);
mi.setProcess(...);
mi.setUpdate(...);
mi.setActionExpression(FacesAccessor.createMethodExpression(
    "#{navigationContext.setBreadcrumbSelection}", String.class, new Class[] {}));

UIParameter param = new UIParameter();
param.setId(...);
param.setName(...);
param.setValue(...);
mi.getChildren().add(param);

Do you have nice methods you want to share here? Tips / tricks are welcome.

Reference: 5 useful methods JSF developers should know from our JCG partner Oleg Varaksin at the Thoughts on software development blog.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

5 Responses to "5 useful methods JSF developers should know"

  1. abani behera says:

    Hi, you have provided nice article. I want to add few comments on the your first section (
    getManagedBean method). from your code snippet, it looks you are using JSF2. If so, getting an instance of managed bean is pretty easy. We have one annotation  
     through which we can get the instance of any object, which is maintained by FacesServlet.
    Below I have given a sample code.

    @ManagedBean:disqus  @SessionScope:disqus 
    public class PersonBean {}public class AccountBean{ @ManagedProperty:disqus  (“#sessionScope.PersonBean”) private PersonBean person; // must have getter/setter for PersonBean}

  2. Oleg Varaksin says:

    Hi, I know about ManagedProperty. But it’s an injection and as I said in the article “Injection is good, but sometimes if beans are rare called, it’s not necessary to inject beans into each other”.

    • Cooljnr says:

      Hi,developing online exam test (multiple choices question)with jsf in java ee but do not know to go about it.please l need your help.thank you

  3. Jorge Pacheco says:

    Hi, I have a problem with the example ‘create MethodExpression’ with menuModel.
    When the menu is inside an accordion, the actionExpresion not working.

    Any ideas?
    thanks

  4. Rafael says:

    Oleg these methods are excellent. Especially first one, I agree with you about injection sometimes it’s not necessary to initialize every beans at the same time. Thank for this article!

Leave a Reply


4 × one =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close