构建一个小应用程序来处理变量。 第一步是解决变量之间的简单依赖关系。 我无法让事情正常运行。 我可以解决非常简单的声明,如a = 10,但如果它变得更复杂,它总是会失败,如: A = B; B = 10。 我将代码缩减为以下几行:
import javax.el.BeanELResolver;
import javax.el.ELContext;
import javax.el.ELResolver;
import javax.el.ExpressionFactory;
import javax.el.FunctionMapper;
import javax.el.ValueExpression;
import javax.el.VariableMapper;
import org.jboss.el.ExpressionFactoryImpl;
import org.jboss.el.lang.VariableMapperImpl;
public void testEvalutation() throws Exception{
ExpressionFactory factory = new ExpressionFactoryImpl();
ELContext context = new ELContext() {
final ELResolver elResolver = new BeanELResolver();
final VariableMapper variableMapper = new VariableMapperImpl();
public ELResolver getELResolver() { return elResolver; }
public FunctionMapper getFunctionMapper() { return null; }
public VariableMapper getVariableMapper() { return variableMapper; }
};
ValueExpression a = factory.createValueExpression(context, "#{b}", Float.class);
ValueExpression b = factory.createValueExpression(context, "#{c}", Float.class);
ValueExpression c = factory.createValueExpression(context, "#{10}", Float.class);
context.getVariableMapper().setVariable("a",a);
context.getVariableMapper().setVariable("b",b);
context.getVariableMapper().setVariable("c",c);
ValueExpression expression = context.getVariableMapper().resolveVariable("a");
assertEquals(10f,expression.getValue(context));
}
'a'的结果是0.0。 是否有任何错误,或者您是否知道我可以运行代码的方式?
感谢您提出任何建议
答案 0 :(得分:0)
我已经深入研究了EL实现,它对表达式创建和映射的排序很敏感。
当ExpressionFactory创建ValueExpression时,它会解析表达式并使用VariableMapper绑定从那里解析的任何表达式。因此,当您设置 a 时,它将无法解析 b ,因为它尚未设置。
结果,#{b}
解析为 null ,然后将其强制转换为 Float ,结果为 0.0 。
以下代码解析为值 10.0 :
ValueExpression c = factory.createValueExpression(context, "#{10}", Float.class);
context.getVariableMapper().setVariable("c", c);
ValueExpression b = factory.createValueExpression(context, "#{c}", Float.class);
context.getVariableMapper().setVariable("b", b);
ValueExpression a = factory.createValueExpression(context, "#{b}", Float.class);
context.getVariableMapper().setVariable("a", a);
ValueExpression expression = context.getVariableMapper().resolveVariable("a");
System.out.println(expression.getValue(context));
请注意,这与解析ELResolver中的变量时发生的情况不同。
我使用了不同的实现(EL 2.2; Java EE 6 equiv),但我希望JBoss实现中有类似的行为。
答案 1 :(得分:0)
我找到了一个像我需要的解决方案。它不依赖于排序和解决变量的任何复杂性:
public class ElVariableResolver extends ELResolver {
[...]
protected final HashMap<String, Variable> variablesMap = new HashMap<String, Variable>();
public ElVariableResolver(final Collection<Variable> variables) {
this.variables = new HashSet<Variable>(variables);
Iterator<Variable> iterator = variables.iterator();
while (iterator.hasNext()) {
Variable v = iterator.next();
this.variablesMap.put(v.getName(), v);
}
[...]
final FunctionMapperImpl functionMapper = new FunctionMapperImpl();
this.expressionFactory = new ExpressionFactoryImpl();
this.elContext = createELContext(this, functionMapper);
}
private static ELContext createELContext(final ELResolver resolver, final FunctionMapper functionMapper) {
return new ELContext() {
final VariableMapperImpl variableMapper = new VariableMapperImpl();
@Override
public ELResolver getELResolver() {
return resolver;
}
@Override
public FunctionMapper getFunctionMapper() {
return functionMapper;
}
@Override
public VariableMapper getVariableMapper() {
return variableMapper;
}
};
}
public Object getVariableValue(final Variable variable) {
String el;
final Class<?> type;
final String value = variable.getValue();
switch (variable.getVariableType()) {
case NUMBER:
el = value.trim();
type = Float.class;
break;
[...]
final String expression = String.format("${%s}", el);
ValueExpression ve = expressionFactory.createValueExpression(this.elContext, expression, type);
Object result = ve.getValue(this.elContext);
return result;
}
}
@Override
public Object getValue(ELContext context, Object base, Object property) {
if ((base == null) && (property != null)) {
Variable v = this.variablesMap.get(property);
if (v != null) {
return this.getVariableValue(v);
}
}
return "TODO";
}
}
public class ElVariableResolverTest extends TestCase{
private final Variable l = new Variable("L",NUMBER,"M");
private final Variable m = new Variable("M",NUMBER,"N");
private final Variable n = new Variable("N",NUMBER,"10");
private ElVariableResolver resolver;
public void testEvaluation() {
final List<Variable> variables = Arrays.asList(l,m,n);
resolver = new ElVariableResolver(variables);
assertEquals(new Float(10),resolver.getVariableValue("L"));
}
}