简体   繁体   中英

How do I avoid MVEL PropertyAccessExceptions

How do you get around PropertyAccessExceptions when the top level key in the hash map may or may not exist?

In the example below, if the property exists, it works just fine, but if the property does not exist in the variable map, it throws a PropertyAccessExceptions. I am aware that I can use the ? for null safe navigation, but this does not work when the property exists on the top level.

Any suggestions?

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

I would like a workaround to avoid PropertyAccessExceptions.

I was facing the same issue recently and I found out MVEL has different methods for evaluating expression one of which is, for boolean, public static Boolean evalToBoolean(String expression, VariableResolverFactory vars) . When you pass Map of variable it internally instantiates CachingMapVariableResolverFactory , which you can override to avoid this issue.

Sample implementation as below

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;
        }
    }

This class will make sure whenever PropertyAccessor checks if variable is present in context of evaluation, it puts a null in case it's not and returns true, avoiding PropertyAccessExceptions. This custom implementation of VariableResolverFactory can be used as below.

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

I don't know if this is a hack or it meant to be used like this but it works

只需在 MVEL 脚本中为您的属性添加前缀“?”,并将其评估为空:

result = MVEL.evalToBoolean("?aValue != null && ?aValue == aNonExistentProperty", variables);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM