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