0

我最近继承了一个遗留 (JSF 1.2) 项目,并负责使其与 JSF 2.2 兼容。我不是一位经验丰富的 JSF 开发人员,并且一直在听从网络上的各种建议。我遇到的一个问题是我找不到合适的解决方案,那就是通过表达式语言参数将方法绑定传递给自定义组件。这是一个例子:

浏览.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. 这一切似乎有点像 hack,更不用说没有像之前的 JSF 1.2 代码那样完成 facelet 中的 EL 表达式求值。

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

编辑:这是我的“hack”,有点工作。希望有更好的方法。

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>

}
4

0 回答 0