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

empty


如果以下条件为真,则应评估为真。

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

布尔值是假的

数值为0

但是它并没有给出期望的结果。


对于字符串,当字符串长度> 0但仅由空格组成时,条件条件评估为false(下面提供了使用的代码)。

String stringValue="     ";
Map<String,Object> contextMap=new HashMap<String, Object>();
contextMap.put("stringValue", stringValue);
System.out.println(MVEL.eval("stringValue == empty",contextMap));

对于布尔值,不管布尔值如何,它都将变为false(下面给出了使用的代码);

Boolean booleanValue=false;
Map<String,Object> contextMap=new HashMap<String, Object>();
contextMap.put("booleanValue", booleanValue);
System.out.println(MVEL.eval("booleanValue == empty",contextMap));

并且在比较整数时显示错误。
码:

    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问题有关。

对于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中完全实现

07-24 22:17