【问题标题】:How to test EL expressions correctness statically?如何静态测试 EL 表达式的正确性?
【发布时间】:2010-10-14 14:01:56
【问题描述】:

在我们的 Web 应用程序中,我们对 Java bean 进行了一些重构,由于这种重构,一些操作/getter 不再可用。例如,在以下示例中:

public class MyBean implements Serializable {

    // Old name
    // public String getFoo() { return "foo"; }

    // New name
    public String getBar() { return "bar"; }

}

如果我的 JSF 代码仍然是这样的:

<h:inputText value="#{myBean.foo}" .../>

然后它会产生一个异常。

我主要担心的是某些 EL 表达式现在可能指向 Java bean 上不存在的方法,而我只有在浏览适当的页面时才能看到这一点。当 EL 表达式位于在特定条件下渲染和/或由 Ajax 重新渲染的部分时,它变得更加困难。

所以我的问题是如何静态检查这些 EL 表达式的正确性?

我检查了JSFUnit 工具,因为它提供了这样的实用程序。所以我尝试了this example,但它似乎没有按预期工作。在一个简单的测试页面上,EL 表达式很少(有些是正确的,有些是错误的,因为不存在的 bean 和/或方法),测试成功,这是不正确的。

一个非常重要的说明:我的 bean 是在我的 Spring 配置中定义的,而 不是faces-config.xml 中。

另外请注意,我只需要检查 EL 表达式是否引用了现有的 bean 和方法,不一定会正确执行此操作...

技术资料:

Java 1.6、Spring 2.5、JSF 1.2、EL Functor、Facelets 和 Richfaces 3.3

【问题讨论】:

  • JSFUnit(至少 1.3.0,但我猜 2.0.0.Beta2 也是如此)仅验证动作和动作侦听器。有一个请求也支持对 getter 的检查,但它已被无限期推迟,请参阅 issues.jboss.org/browse/JSFUNIT-140 。感谢您分享您的解决方案!

标签: testing jsf el


【解决方案1】:

我没有找到符合我要求的工具。所以我在我的应用程序上写了一个小豆子。此 bean 将提供一个操作,该操作将读取一个目录并分析其中的每个 .xhtml 文件(并以递归方式执行此操作)。当然,我必须运行我的应用程序(所以分析不是真正静态的),但是这个解决方案的优点是我可以访问我真正在我的网络应用程序中使用的ELContextELExpressionFactory,都链接到我的 Spring 上下文。

这是代码中有趣的部分:

// Analyse a XHTML file
private void analyzeXHTMLFile(File f) throws IOException {
    List<String> lines = FileUtils.readLines(f);
    for (String l : lines) {
        List<String> els = getEL(l);
        for (String el : els) {
            evaluateEL(el);
        }
    }
}

// Get a List of EL on the line.
private List<String> getEL(String line) {
    List<String> el = new ArrayList<String>();
    int i = line.indexOf("#{");
    if (i == -1) {
        return el;
    }
    while (i != -1) {
        int j = line.indexOf("}", i);
        if (j == -1) {
            return el;
        }
        el.add(line.substring(i, j + 1));
        i = line.indexOf("#{", i + 1);
    }
    return el;
}

// Evaluate the EL
private void evaluateEL(String el) {
    FacesContext context = FacesContext.getCurrentInstance();
    ELContext elContext = context.getELContext();
    ValueExpression ve = context.getApplication().getExpressionFactory().createValueExpression(elContext, el, Object.class);
    if (ve != null) {
        Object o = null;
        try {
            o = ve.getValue(elContext);
        } catch (PropertyNotFoundException pnfe) {
            // Handle this error
        }
        if (o == null) {
            // Handle another error
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-16
    • 1970-01-01
    • 2012-06-02
    • 1970-01-01
    • 1970-01-01
    • 2011-06-12
    • 1970-01-01
    相关资源
    最近更新 更多