在我们的Web应用程序中,我们对Java bean进行了一些重构,由于这种重构,一些操作/获取器不再可用.例如,在以下示例中:
public class MyBean implements Serializable {
// Old name
// public String getFoo() { return "foo"; }
// New name
public String getBar() { return "bar"; }
}
Run Code Online (Sandbox Code Playgroud)
如果我的JSF代码仍然如下:
<h:inputText value="#{myBean.foo}" .../>
Run Code Online (Sandbox Code Playgroud)
那么它会产生一个例外.
我主要担心的是,一些EL表达式现在可能指向Java bean上的未使用的方法,而我只能在浏览适当的页面时看到它.当EL表达式位于特定条件下呈现的部分和/或由Ajax重新呈现时,它变得更加困难.
所以我的问题是如何静态检查这些EL表达式的正确性?
我检查了JSFUnit工具,因为它提供了这样的实用程序.所以我尝试了这个例子,但它似乎没有按预期工作.在一个简单的测试页面上,只有很少的EL表达式(一些是正确的,一些其他错误的未发布的bean和/或方法),测试成功,这是不正确的.
一个非常重要的注意事项:我的bean是在我的Spring配置中定义的,而不是在我的faces-config.xml.
另请注意,我只需要检查EL表达式是否引用现有的bean和方法,而不一定是这个动作将被正确执行...
技术信息:
Java 1.6,Spring 2.5,JSF 1.2,EL Functor,Facelets和Richfaces 3.3
我没有找到符合我要求的工具。所以我在我的申请中写了一个小豆子。该 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
}
}
}
Run Code Online (Sandbox Code Playgroud)