Компиляция выражения Mvel прошла, но оценка не удалась - PullRequest
3 голосов
/ 21 октября 2019

Я использую Mvel API mvel2 2.4.4.Final для написания некоторой логики, основанной на правилах, в моем веб-приложении java.

У меня есть список Mvel Expressions, который необходимо скомпилировать, прежде чем использовать их в реальных операциях, чтобы избежатьлюбые недопустимые проблемы с выражением во время запросов клиента.


Выражение Mvel

Это один из моих Mvel Expression, который я хочу скомпилировать

a.totalAmount <= 30 && a.currency == "981" && a.merchantId == testMerchant


Объект транзакции

Этот класс содержит все свойства, которые используются в Mvel expressions

public class Transaction {
  private String merchantId;
  private double totalAmount;
  private String currency;  
  ...
}

Код подтверждения выражения

public static void compile(List<Rule> ruleList)  {   
    ruleList.forEach(rule -> {
      ParserContext context = new ParserContext();
      context.setStrictTypeEnforcement(true);
      context.addInput("a", Transaction.class);
      MVEL.compileExpression(rule.getMvelExpression(), context);
      }
    });
  }

Приведенный выше код проверки не улавливает никаких ошибок при компиляции Mvel expression, и компиляция успешно завершается, но когда программа пытается сравнить значения transaction object со значениями Mvel expression, используя этот код ниже, она выдает org.mvel2.PropertyAccessException


Оценочный код

  public void eval(Rule rule, Transaction tran) {
    Map<String, Object> inputContext = new HashMap<>();
    inputContext.put("a", tran);
    MVEL.eval(rule.getMvelExpression(), inputContext);
  }

Сведения об исключении

[Near : {... t <= 30 && a.currency == "981" && a.merchantId == testMerchant ....}]
                                                               ^
[Line: 1, Column: 63] }}} 
org.mvel2.PropertyAccessException: [Error: unresolvable property or identifier: testMerchant]
[Near : {... t <= 30 && a.currency == "981" && a.merchantId == testMerchant ....}]
                                                               ^
[Line: 1, Column: 63]
    at org.mvel2.PropertyAccessor.getBeanProperty(PropertyAccessor.java:676) ~[mvel2-2.4.4.Final.jar:?]
    at org.mvel2.PropertyAccessor.getNormal(PropertyAccessor.java:178) ~[mvel2-2.4.4.Final.jar:?]
    at org.mvel2.PropertyAccessor.get(PropertyAccessor.java:145) ~[mvel2-2.4.4.Final.jar:?]
    at org.mvel2.PropertyAccessor.get(PropertyAccessor.java:125) ~[mvel2-2.4.4.Final.jar:?]
    at org.mvel2.ast.ASTNode.getReducedValue(ASTNode.java:187) ~[mvel2-2.4.4.Final.jar:?]
    at org.mvel2.MVELInterpretedRuntime.parseAndExecuteInterpreted(MVELInterpretedRuntime.java:145) ~[mvel2-2.4.4.Final.jar:?]
    at org.mvel2.MVELInterpretedRuntime.parse(MVELInterpretedRuntime.java:47) ~[mvel2-2.4.4.Final.jar:?]
    at org.mvel2.MVEL.eval(MVEL.java:165) ~[mvel2-2.4.4.Final.jar:?]

Как вы можете видеть в Исключениипроблема в том, что значение a.merchantId в Mvel Expression не в кавычках,если я добавлю такие кавычки a.merchantId == "testMerchant", то все будет нормально.

Но из-за документации Mvel API:

enter image description here enter image description here


Вопрос

  1. Почему код MVEL.eval(rule.getMvelExpression(), inputContext); вызывает исключение, если MVEL автоматически присваивает правильный тип a.merchantId по концепции приведения значений?
  2. Почему компилятор не ловит это исключение и как Coercion Mvel его ловить?
  3. Почему возникает исключение org.mvel2.PropertyAccessException: [Error: unresolvable property or identifier: testMerchant], когда проблема в кавычках?
...