当哈希映射中的顶层密钥可能存在或不存在时,如何解决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的解决方法。
答案 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))
我不知道这是黑客还是本该使用的方式,但有效