繁体   English   中英

为具有不同变量类型的MVEL创建上下文

[英]creating context for MVEL with different variable types

我正在使用MVEL评估算术和逻辑表达式或两者的组合。 事实是,我事先不知道所有变量类型,而没有为表达式本身(通过设置文件传递)创建非常复杂的解析方法。 我只有在浏览数据并更新上下文时才知道它们的类型。 例如,考虑表达式(a && b) && (c == 10) && (d < 5)我从运算符中分离了变量并初始化了我的上下文,但是我不知道哪个是布尔值,哪个是整数。 我试图用nullnew 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 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)初始化它们,但这会影响表达式。 我必须使用严格输入还是强类型输入? 顺便说一句,我找不到这些类的任何体面的文档..任何建议,不胜感激。 谢谢。

首先,您可以要求MVEL自动获取输入变量。 不幸的是,MVEL不会告诉您它认为对象类型是什么。 因此,例如:

Public class MvelVarTest {

public static void main(String[] args) {
    String expression = "( a > b + 2 ) && ( c < a - 5 )";
    ParserContext context = new ParserContext();
    Serializable compiledExpression = MVEL.compileExpression(expression, context);

    //Now the context will have a list of all the inputs.  Unfortunatly it does not tell you what type of Object the input is.
    for (Map.Entry<String,Class> entry : context.getInputs().entrySet()) {
        System.out.println("Variable name : "+entry.getKey()+", Data Type = "+entry.getValue().toString());
    }

    //Now, you can assign values to the data and run the expression.
    Map values = new HashMap();
    values.put("a",25);
    values.put("b",20);
    values.put("c",10);

    //And we can get a boolean answer
    System.out.println("Result of running formula with (a=25, b=20, c=10) = "+MVEL.executeExpression(compiledExpression,values,Boolean.class));
}

}

但是,当使用值设置HashMap时,可以只放入字符串值,而MVEL可以“自动转换”它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM