我最近继承了遗留(JSF 1.2)项目,并且其任务是使其符合JSF 2.2标准 . 我不是一位经验丰富的JSF开发人员,并且一直在关注网络上的各种建议 . 我遇到的一个无法找到适当解决方案的问题是通过表达式语言参数将方法绑定传递给自定义组件 . 这是一个例子:

browse.xhtml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html lang="en"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:custom="http://www.custom.com/jsf/custom">

<f:view>
    <head>
    <title>Title</title>
    </head>
    <body>
        <custom:condition test="#{MyBean.canView}">
            Some private data here
        </custom:condition>
    </body>
</f:view>
</html>

MyBean.java:

public class MyBean {
    public String canView() { return "true"; }
}

Conditional.java(映射到custom:condition标签):

public class Conditional extends UIComponentBase {

    <snip>

    private MethodBinding testBinding;

    public MethodBinding getTest() {
        return testBinding;
    }

    public void setTest(MethodBinding test) {
        testBinding = test;
    }

    public boolean test(FacesContext context) {
        boolean ret = true;
        if (testBinding != null) {
            try {
                Object o = testBinding.invoke(context, null);
                ret = o != null;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return ret;
    }

    <snip>

}

我已经通过传递一个 String 表达式(例如 "MyBean.canView" )来关闭EL哈希/大括号,然后在组件中重新连接它们并创建和调用 MethodExpression ,从而得到了一些基本代码 . 这一切似乎都是一个黑客,更不用说没有完成facelet中的EL表达式评估,就像之前的JSF 1.2代码那样 .

我错过了什么吗?这个JSF 1.2代码应该如何转换为JSF 2.2?

编辑:这是我的“黑客”,有点,sorta工作 . 希望有更好的方法 .

public class Conditional extends UIComponentBase {

    <snip>

    public boolean test(FacesContext context) {
        if (testBinding != null) {
            Object ret = null;
            try {
                ApplicationFactory factory = (ApplicationFactory) FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);      
                MethodExpression methodExpression = factory.getApplication().getExpressionFactory().createMethodExpression(
                FacesContext.getCurrentInstance().getELContext(), 
                    "#{" + testBinding + "}", Boolean.class, new Class[] {});
                ret =   methodExpression.invoke(FacesContext.getCurrentInstance().getELContext(), null);
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (ret == null) return false;
        }
        return true;
    }

    <snip>

}