我有一個應用程序,其中包含用於編程配置的一些EL評估。給定一個EL表達式,我想得到它包含的自由變量而不實際評估它。目的是提供一個用戶界面,最終用戶可以在按下「評估」按鈕之前將值綁定到自由變量。列出EL表達式中的自由變量
不幸的是javax.el.ValueExpression
不提供此功能,所以我可能需要使用供應商特定的API。這是在開發早期,所以我還沒有確定我的選擇實施。我曾經想過MVEL,JUEL和SpEL,但是當然我選擇的應該有我上面描述的功能。
我有一個應用程序,其中包含用於編程配置的一些EL評估。給定一個EL表達式,我想得到它包含的自由變量而不實際評估它。目的是提供一個用戶界面,最終用戶可以在按下「評估」按鈕之前將值綁定到自由變量。列出EL表達式中的自由變量
不幸的是javax.el.ValueExpression
不提供此功能,所以我可能需要使用供應商特定的API。這是在開發早期,所以我還沒有確定我的選擇實施。我曾經想過MVEL,JUEL和SpEL,但是當然我選擇的應該有我上面描述的功能。
MVEL的ParserContext可以告訴你所有的當地人和投入舉辦的變量。
ParserContext ctx = ParserContext.create();
MVEL.analysisCompile("a = 0; b = 0;", ctx);
HashMap<String, Class> vars = ctx.getVariables();
assert vars.containsKey("a") && Number.class.isAssignableFrom(vars.get("a"));
assert vars.containsKey("b") && Number.class.isAssignableFrom(vars.get("b"));
這個怎麼樣...
SpelExpression parseExpression = (SpelExpression) new SpelExpressionParser().parseExpression(expressionString);
SpelNode node = parseExpression.getAST();
List<String> vars = getVars(node);
...
private List<String> getVars(SpelNode node) {
List<String> vars = new ArrayList<String>();
for (int i = 0; i < node.getChildCount(); i++) {
SpelNode child = node.getChild(i);
if (child.getChildCount() > 0) {
vars.addAll(getVars(child));
}
else {
if (child instanceof VariableReference) {
vars.add(child.toStringAST());
}
}
}
return vars;
}
Gary的回答很好,但當表達式包含單個變量時,它不起作用。 「#var」(一個沒有孩子的節點)。一個小小的變化:
private Set<String> getVars(SpelNode node) {
Set<String> vars = new HashSet<String>();
if (node == null) {
return vars;
}
if (node instanceof VariableReference) {
// Remove the "#" to get the actual variable name
vars.add(StringUtils.remove(node.toStringAST(), "#"));
}
for (int i = 0; i < node.getChildCount(); i++) {
SpelNode child = node.getChild(i);
vars.addAll(getVars(child));
}
return vars;
}
它看起來很有趣。 – Saintali 2012-08-07 12:32:52