PropertyAccessExceptions

PropertyAccessExceptions

当哈希映射中的顶层密钥可能存在或不存在时,如何解决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的解决方法。

最佳答案

我最近遇到了同样的问题,我发现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))

我不知道这是hack还是打算像这样使用,但可以

10-04 19:14