我正在使用 MVEL 来评估算术和逻辑表达式或两者的组合。问题是我事先并不知道所有变量类型,而没有为表达式本身创建一个非常复杂的解析方法(通过设置文件传递)。只有当我浏览我的数据并更新上下文时,我才知道它们的类型。例如,考虑将(a && b) && (c == 10) && (d < 5)
变量与运算符分开并初始化上下文的表达式,但我不知道哪些是布尔值,哪些是整数。我试图用null
or初始化上下文中的所有变量,new Object()
但它没有按预期工作。请参见下面的示例代码:
import java.util.HashMap;
import java.util.Map;
import org.mvel2.MVEL;
public class Test {
private static Map<String, Object> context = new HashMap<String, Object>();
public static void main(String[] args){
String expression = "(a && b) && (c == 10) && (d < 5)";
context.put("a", new Object());
context.put("b", new Object());
context.put("c", new Object());
context.put("d", new Object());
//do some processing and get the right value, replacing it in the context with the right type
evaluate(expression,context); //just to try to evaluate with nothing set, crashes
context.put("a", new Boolean(true));
evaluate(expression,context);//crashes same as above
context.put("b", new Boolean(true));
evaluate(expression,context); //works. the expression is not yet true but it does not crash
context.put("c", new Integer(10));
context.put("d", new Integer(1));
evaluate(expression,context); //works. expression is true
}
private static void evaluate(String expression, Map<String,Object> context){
if((Boolean)MVEL.eval(expression, context))
System.out.println("Hooray");
else
System.out.println("Boo!");
}
}
当它崩溃时,我收到这条消息:Exception in thread "main" org.mvel2.ScriptRuntimeException: expected Boolean; but found: java.lang.Object
如果我用它初始化null
会崩溃说..but found: null
我的猜测是它在MVEL.eval()方法中计算出它应该接收布尔值作为第一个变量,但我发现行为不一致。第二个例子让我更加困惑。请参见下面的示例代码:
import java.util.HashMap;
import java.util.Map;
import org.mvel2.MVEL;
public class Test {
private static Map<String, Object> context = new HashMap<String, Object>();
public static void main(String[] args){
context.put("a", null);
context.put("b", null);
context.put("c", null);
String expression = "( a > b + 2 ) && ( c < a - 5 )";
evaluate(expression,context); //this time it does not crash. it evaluates correctly as false
//do some processing and get the right value, and replace it in the context
context.put("a",new Integer(25));
evaluate(expression,context); //crashes. error below
context.put("b", new Integer(20));
context.put("c", new Integer(10));
evaluate(expression,context); //evaluates correctly to true.
}
private static void evaluate(String expression, Map<String,Object> context){
if((Boolean)MVEL.eval(expression, context))
System.out.println("Hooray");
else
System.out.println("Boo!");
}
}
第二个示例中的崩溃错误消息是:Exception in thread "main" [Error: failed to subEval expression]
[Near : {... ( a > b + 2 ) && ( c < a - 5 ) ....}]
^
我的上下文变量是否有默认初始化?我可以用初始化它们,new Boolean(false)
但这会影响表达式。我必须使用严格类型或强类型吗?顺便说一句,我没有找到任何像样的类文档..任何建议都值得赞赏。谢谢你。