【问题标题】:MVEL not working as desired for empty comparisonMVEL 无法按需要进行空比较
【发布时间】:2015-01-02 20:45:24
【问题描述】:

根据 [http://mvel.codehaus.org/Value+Emptiness 中的 MVEL 文档

empty

如果下面提到的条件为真,则应评估为真。

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

一个布尔值是假的

数值为 0

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

  1. 当字符串长度>0但仅包含空格(使用的代码如下)时,字符串案例条件评估为假。

    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));
    

错误:

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

为什么它没有按照文档工作?

【问题讨论】:

  • 一种被称为“虫子”的物种在软件和其他牧场上被发现。在 MVEL 错误报告网站上提交错误报告。
  • @laune 找不到任何报告错误的链接(公开)。如果有链接请分享。
  • 我已经开始查询了。请稍候。
  • @laune 分享了我的分析,希望您提供一种记录错误的方法
  • @sud_shan 这是一个错误,找到一个替代方案。 :)

标签: java comparison mvel isnullorempty


【解决方案1】:

这三个都与 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 强制转换为 Number,控制权交给此类 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 中完全实现

【讨论】:

    【解决方案2】:

    我在这个提交中添加了空文字的缺失实现部分:https://github.com/mvel/mvel/commit/b44824e9ccbc565b6619714c92582014271e4bbb

    该修复将在下一个 mvel 版本 (2.2.3.Final) 中提供。感谢您报告此事。

    【讨论】:

    • 感谢您的快速修复,将等待下一个版本。
    • @Mario Fusco 非常感谢
    猜你喜欢
    • 1970-01-01
    • 2020-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多