简体   繁体   English

Mvel评估

[英]Mvel evaluation

Problem Statement: Say I have a expression (a + b + c) , and I want to calculate its value and assign to some variable. 问题陈述:假设我有一个表达式(a + b + c) ,我想计算它的值并分配给某个变量。 Later I want use that variable value in some other logic. 后来我想在其他逻辑中使用该变量值。 This is all done through MVEL. 这一切都是通过MVEL完成的。 Issue is if anyone out of (a,b,c) is null , MVEL evaluates in a string format. 问题是如果(a,b,c)任何(a,b,c)null ,MVEL将以字符串格式进行求值。

So to avoid this, I created my own function to pass each object and if it is null, make it zero. 所以为了避免这种情况,我创建了自己的函数来传递每个对象,如果它是null,则将其设为零。

Sample code below 示例代码如下

public class MvelTest {

    public static void main(String[] args) {

        Map map = new HashMap();

        VariableResolverFactory functionFactory = new MapVariableResolverFactory(map);
        MVEL.eval("checkNullValue = def (x) { x == null ? 0 : x };", functionFactory);

        map.put("a", null);
        map.put("b", 1);
        map.put("c", 1);

        Serializable str = MVEL.compileExpression("( ( checkNullValue(a) + checkNullValue(b) + checkNullValue(c) ) > 2 ) ? d=2 : d=3");

        MVEL.executeExpression(str, map, functionFactory);
        System.out.println(map);
        System.out.println(map.get("d"));
    }
}

Output 产量

{checkNullValue=function_prototype:null, b=1, c=1, a=null}
null

I am not able to get value of "d" here, and if I remove factory and null check function it behaves and I am able to get the value of "d" . 我无法在这里得到"d"值,如果我删除了工厂和空检查功能,它的行为和我能够得到"d"的值。 But I have to make it null safe for arithmetic operation, Since MVEL cannot handle this. 但是我必须使它对算术运算是安全的,因为MVEL无法处理这个问题。

Also (null * 23) , MVEL returns as false . 另外(null * 23) ,MVEL返回false

The problem is with your ternary operator. 问题出在您的三元运营商身上。 I am not sure how MVEL evaluates those (the way you use them would be illegal in Java), but it seems like putting the assignment in the then/else part does not work... or rather, it (for whatever reason) does work for the 'then' part (before : ) but fails for the 'else' part (after : ). 我不知道MVEL如何评估那些(你使用它们会在Java中非法的方式),但它似乎是把分配在当时的/其他部分不工作......或者说,它(无论何种原因) 为'then'部分工作(在:之前),但在'else'部分工作(在:之后)。

So if the sum is > 2 it works, whether or not you are using the null-check function, and otherwise it fails. 因此,如果总和> 2它是否有效,无论您是否使用空检查功能,否则它将失败。

You should fix your expression and put the assignment in front of the ternary operator: 你应该修复你的表达式并将赋值放在三元运算符的前面:

MVEL.compileExpression("d = cnv(a) + cnv(b) + cnv(c) > 2 ? 2 : 3")

Update: Generally, this is what I observed, independently of a , b , c , and cnv : 更新:通常,这是我观察到的,独立于abccnv

MVEL.compileExpression("true  ? d=1 : d=2"); // d ends up as 1
MVEL.compileExpression("false ? d=1 : d=2"); // d is null / unknown
MVEL.compileExpression("d = guard ? 1 : 2"); // always works

Issue got resolved, i was actually creating the static reference for VariableResolverFactory and was referring the same for every evaluation, i changed it to new instance for every execution and it worked. 问题得到解决,我实际上是为VariableResolverFactory创建静态引用,并且每次评估都引用相同的内容,我将其更改为每次执行的新实例并且它有效。

 public VariableResolverFactory getMvelFactory(Map contextMap) {
        VariableResolverFactory functionFactory = new MapVariableResolverFactory(contextMap);
        MVEL.eval("checkNullValue = def (x) { x == null ? 0 : x };", functionFactory);

        return functionFactory;
    }

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

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