如何避免MVEL PropertyAccessExceptions

时间:2019-07-04 14:37:39

标签: java mvel

当哈希映射中的顶层密钥可能存在或不存在时,如何解决PropertyAccessExceptions?

在下面的示例中,如果该属性存在,则可以正常工作,但是如果该属性在变量映射中不存在,则将引发PropertyAccessExceptions。我知道我可以使用?用于null安全导航,但是当该属性位于顶层时,此功能将无效。

有什么建议吗?

HashMap<String, Object> variables = new HashMap<>();
variables.put("aProperty", "aValue");

Boolean result = MVEL.evalToBoolean("'aValue' == aProperty", variables);
assertThat(result).isTrue();  //This works

result = MVEL.evalToBoolean("'aValue' == aNonExistentProperty", variables);
assertThat(result).isFalse();  //This throws a PropertyAccessException, since aNonExistentProperty is not defined

我想要一种避免PropertyAccessExceptions的解决方法。

1 个答案:

答案 0 :(得分:2)

我最近遇到了同样的问题,我发现MVEL有不同的方法来评估表达式,其中一种是布尔值public static Boolean evalToBoolean(String expression, VariableResolverFactory vars)。当传递变量Map时,它会在内部实例化CachingMapVariableResolverFactory,您可以重写它以避免发生此问题。

示例实现如下

public class CustomVariableResolvableFactory extends CachingMapVariableResolverFactory{
        public CustomVariableResolvableFactory(Map variables) {
            super(variables);
        }
        @Override
        public boolean isResolveable(String name) {
            if(!super.isResolveable(name))
                variables.put(name, null);
            return true;
        }
    }

此类将确保每当PropertyAccessor检查变量是否存在于评估上下文中时,如果不存在该变量,则将其放置为null并返回true,从而避免PropertyAccessExceptions。 VariableResolverFactory的此自定义实现可按以下方式使用。

MVEL.eval(expression, new CustomVariableResolvableFactory(vars))

我不知道这是黑客还是本该使用的方式,但有效