MVEL无法按照空对比的方式工作

时间:2014-12-20 20:51:38

标签: java comparison mvel isnullorempty

根据[http://mvel.codehaus.org/Value+Emptiness

中的MVEL文档
empty
如果下面提到的条件成立,

应评估为真。

字符串的长度大于0但仅包含空格

布尔值为false

数值为0

但它没有给出理想的结果。

  1. 对于字符串情况,当字符串长度> 0时评估为false,但仅包含空格(下面给出使用的代码)。

    String stringValue="     ";
    Map<String,Object> contextMap=new HashMap<String, Object>();
    contextMap.put("stringValue", stringValue);
    System.out.println(MVEL.eval("stringValue == empty",contextMap));
    
  2. 对于布尔值,无论布尔值如何,它都会变为假(使用的代码如下);

    Boolean booleanValue=false;
    Map<String,Object> contextMap=new HashMap<String, Object>();
    contextMap.put("booleanValue", booleanValue);
    System.out.println(MVEL.eval("booleanValue == empty",contextMap));
    
  3. 它显示比较整数时出错。 代码:

        Integer integerValue=0;
        Map<String,Object> contextMap=new HashMap<String, Object>();
        contextMap.put("integerValue", integerValue);
        System.out.println(MVEL.eval("integerValue == empty",contextMap));
    
  4. 错误:

    Exception in thread "main" [Error: failed to subEval expression]
    [Near : {... integerValue == empty ....}]
                                 ^
    [Line: 1, Column: 17]
        at org.mvel2.compiler.AbstractParser.reduce(AbstractParser.java:2653)
        at org.mvel2.compiler.AbstractParser.arithmeticFunctionReduction(AbstractParser.java:2552)
        at org.mvel2.MVELInterpretedRuntime.parseAndExecuteInterpreted(MVELInterpretedRuntime.java:152)
        at org.mvel2.MVELInterpretedRuntime.parse(MVELInterpretedRuntime.java:49)
        at org.mvel2.MVEL.eval(MVEL.java:165)
        at com.Test1.main(Test1.java:15)
    Caused by: java.lang.RuntimeException: cannot convert <> to a numeric type: class org.mvel2.compiler.BlankLiteral [200]
        at org.mvel2.math.MathProcessor.getNumber(MathProcessor.java:702)
        at org.mvel2.math.MathProcessor._doOperations(MathProcessor.java:214)
        at org.mvel2.math.MathProcessor.doOperations(MathProcessor.java:79)
        at org.mvel2.math.MathProcessor.doOperations(MathProcessor.java:48)
        at org.mvel2.util.ExecutionStack.op(ExecutionStack.java:178)
        at org.mvel2.compiler.AbstractParser.reduce(AbstractParser.java:2593)
        ... 5 more
    

    为什么它不按文档工作?

2 个答案:

答案 0 :(得分:2)

这三个都与MVEL问题有关。

对于Q1 and Q2

对于empty运算符,MVEL有一个类BlankLiteral,它有一个方法

public boolean equals(Object obj) {
    if (obj == null || "".equals(valueOf(obj))) {
      return true;
    }
    else if (isNumeric(obj)) {
      return "0".equals(valueOf(obj));
    }
    else if (obj instanceof Collection) {
      return ((Collection) obj).size() == 0;
    }
    else if (obj.getClass().isArray()) {
      return getLength(obj) == 0;
    }
    return false;
  }

,它不会处理您在Q1 and Q2 中提出质疑的案件。

Q3,表达式integerValue == empty

MVEl尝试将empty投射到数字,控制权来到此课程MathProcessor.class

方法是

private static Double getNumber(Object in, int type) {
    if (in == null)
      return 0d;
    switch (type) {
      case BIG_DECIMAL:
        return ((Number) in).doubleValue();
      case DataTypes.BIG_INTEGER:
        return ((Number) in).doubleValue();
      case DataTypes.INTEGER:
      case DataTypes.W_INTEGER:
        return ((Number) in).doubleValue();
      case DataTypes.LONG:
      case DataTypes.W_LONG:
        return ((Number) in).doubleValue();
      case DataTypes.STRING:
        return Double.parseDouble((String) in);
      case DataTypes.FLOAT:
      case DataTypes.W_FLOAT:
        return ((Number) in).doubleValue();
      case DataTypes.DOUBLE:
      case DataTypes.W_DOUBLE:
        return (Double) in;
      case DataTypes.SHORT:
      case DataTypes.W_SHORT:
        return ((Number) in).doubleValue();
      case DataTypes.CHAR:
      case DataTypes.W_CHAR:
        return Double.parseDouble(String.valueOf((Character) in));
      case DataTypes.BOOLEAN:
      case DataTypes.W_BOOLEAN:
        return ((Boolean) in) ? 1d : 0d;
      case DataTypes.W_BYTE:
      case DataTypes.BYTE:
        return ((Byte) in).doubleValue();
    }

    throw new RuntimeException("cannot convert <" + in + "> to a numeric type: " + in.getClass() + " [" + type + "]");

}

在调试模式下观察值,

Object in - BlankLiteral
int type - 200

200只是DataTypes.EMPTY,但目前还没有被MVEL处理。因此,由于没有匹配的情况,它会抛出异常。

所以仍然'空'是未在MVEL中完全实现

答案 1 :(得分:1)

我使用此提交添加了空文字的缺失实现部分:https://github.com/mvel/mvel/commit/b44824e9ccbc565b6619714c92582014271e4bbb

下一个mvel版本(2.2.3.Final)将提供此修复程序。谢谢你报告了这个。