当哈希映射中的顶层密钥可能存在或不存在时,如何解决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还是打算像这样使用,但可以