Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

jsf - Programmatically get expression value of facelets parameter (variable)

Following java code allows to access any object or variable from faces context:

ELContext elCtx = facesContext.getELContext();
ExpressionFactory exprFac = facesContext.getApplication().getExpressionFactory();
MyProperty myProperty = (MyProperty) exprFac.createValueExpression(elCtx, "#{somebean.someattr.someproperty}", MyProperty.class).getValue(elCtx);

I use the code from within my custom converter to read additional converting parameters from context.

The code works correctly if #{somebean} is defined as normal backing bean within JSF context.

Facelets allow to create 'shortcut' to JSF expressions. Example:

<ui:param name="shortcut" value="#{somebean.someattr.someproperty}" />
<div>#{somebean.someattr.someproperty} equals #{shortcut}</div>

In this case both #{somebean.someattr.someproperty} and #{shortcut} have the same value.

However these 'shortcut' names are not accessible using java code above. For example:

MyProperty myProperty1 = (MyProperty) exprFac.createValueExpression(elCtx, "#{somebean.someattr.someproperty}", MyProperty.class).getValue(elCtx);
// myProperty1 has expected value

MyProperty myProperty2 = (MyProperty) exprFac.createValueExpression(elCtx, "#{shortcut}", MyProperty.class).getValue(elCtx);
// myProperty2 is null

Is there a way to access a facelets context and to read 'shortcut' parameter values, defined on the current JSF page?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I had the same problem and have chosen the following approach:

/**
     * Führt eine Expression im aktuellen Faces EL Context 
     * UND im Facelets El Context aus.
     * 
     * @param facesContext
     * @param expression
     * @return object
     */
    private static Object executeExpressionInUIContext (final FacesContext facesContext, final String expression) {
        final ELContext elContext = facesContext.getELContext();
        final Application application = facesContext.getApplication();

        Object result = executeExpressionInElContext(application, elContext, expression);
        if (null == result) {
            FaceletContext faceletElContext = (FaceletContext) FacesContext.getCurrentInstance().getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY);
            result = executeExpressionInElContext(application, faceletElContext, expression);
        }
        return result;
    }

    private static Object executeExpressionInElContext (Application application, ELContext elContext, String expression) {
        ExpressionFactory expressionFactory = application.getExpressionFactory();
        ValueExpression exp = expressionFactory.createValueExpression(elContext, expression, Object.class);
        return exp.getValue(elContext);
    }

"ui:param" is part of the Facelet view handling technology. Facelets extends JSF. Both technologies use their own Context when storing variables. Beside the Faces El Context there is a Facelet El Context (FaceletContext).

The stated method evaluates expressions in both contexts. Be aware that this will not work if two values are stored under the same name in each context.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...