代码之家  ›  专栏  ›  技术社区  ›  Romain Linsolas

如何静态测试EL表达式的正确性?

  •  5
  • Romain Linsolas  · 技术社区  · 15 年前

    在我们的Web应用程序中,我们对Java bean进行了一些重构,并且由于这种重构,一些动作/吸气剂不再可用。例如,在下面的示例中:

    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

    1 回复  |  直到 14 年前
        1
  •  1
  •   Romain Linsolas    15 年前

    我找不到符合我要求的工具。所以我在我的应用程序上写了一个小bean。这个bean将提供一个操作,该操作将读取一个目录并分析每个目录 .xhtml 文件(并递归执行此操作)。当然,我必须运行我的应用程序(所以分析不是真正静态的),但是这个解决方案的优点是我可以访问 ELContext ELExpressionFactory 我真的在我的Web应用程序中使用,两者都链接到我的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
            }
        }
    }