Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Expression Language use map as context

Tags:

java

spring

I am using the spring expression language to parse some expressions. I run into a scenario that the context to run the expression against is a map or a dynamic bean created by BeanUtils

Map<String, Object> props= new HashMap<>();
props.put("name", "john");
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext context = new StandardEvaluationContext();
Expression exp = parser.parseExpression("name==john");
boolean s  = exp.getValue(context, Boolean.class);

This blows up as the name is not a public property defined in the context.Any idea of how the spring expression language can be used to achieve such functionality

like image 733
John Kiragu Avatar asked Apr 23 '26 09:04

John Kiragu


2 Answers

There are two errors in your code. First, you need to use single quotes around the literal string 'john' in the expression. Second, you need to pass the variable props as the root object of the context. After fixing these, you need to use MapAcessor as the property accessor to access map properties directly:

    Map<String, Object> props = new HashMap<>();
    props.put("name", "john");
    ExpressionParser parser = new SpelExpressionParser();
    StandardEvaluationContext context = new StandardEvaluationContext(props);
    context.addPropertyAccessor(new MapAccessor());
    Expression exp = parser.parseExpression("name=='john'");
    boolean s  = exp.getValue(context, Boolean.class);
like image 130
Marco Avatar answered Apr 25 '26 21:04

Marco


As @Marco said there are a few modifications that needs to be done.

  1. Use single quotes around the literal string 'john' in the expression.
  2. You need to pass the variable props as the root object of the context.
  3. But we can directly access the Map using SpEL as Mentioned in the documentation

    // Officer's Dictionary
    
    Inventor pupin = parser.parseExpression("Officers['president']").getValue(
            societyContext, Inventor.class);
    
  4. Use #this['name'].Using #this

The variable #this is always defined and refers to the current evaluation object (against which unqualified references are resolved).

After modification the code will look like this :

    Map<String, Object> props= new HashMap<>();
    props.put("name", "john");
    ExpressionParser parser = new SpelExpressionParser();
    EvaluationContext context = new StandardEvaluationContext(props);
    Expression exp = parser.parseExpression("#this['name']=='john'");
    boolean s  = exp.getValue(props, Boolean.class);
like image 31
Vinish George Avatar answered Apr 25 '26 22:04

Vinish George



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!