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.

Related Whitepaper:

Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions

Get ready to program in a whole new way!

Functional Programming in Java will help you quickly get on top of the new, essential Java 8 language features and the functional style that will change and improve your code. This short, targeted book will help you make the paradigm shift from the old imperative way to a less error-prone, more elegant, and concise coding style that’s also a breeze to parallelize. You’ll explore the syntax and semantics of lambda expressions, method and constructor references, and functional interfaces. You’ll design and write applications better using the new standards in Java 8 and the JDK.

Get it Now!  

4 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

Leave a Reply


8 × two =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
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.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books