Home > Software engineering >  Spring expression language: Using a variable as key for a map lookup in SpEL
Spring expression language: Using a variable as key for a map lookup in SpEL

Time:01-24

I'm trying to use variable as key to look up a value in a map. I would like to be able to reference the variable directly (in this case jobTitle), but for some reason I need to prefix the variable with either #root. or #this. in order to get it to work. So this works:

parser.parseExpression("{ \"Manager\":\"37.5\", \"CEO\":\"40\"}[#root.jobTitle]"

(resolves to "37.5")

but this doesn't

parser.parseExpression("{ \"Manager\":\"37.5\", \"CEO\":\"40\"}[jobTitle]"

(resolves to null)

jobTitle is a root attribute on the context object. From looking at the SpEL docs it seems like I should be able to reference the attribute directly? Am I doing something wrong?

Full working code below

public static void main(String[] args) {
    ExpressionParser parser = new SpelExpressionParser();
    Employee employee = new Employee("Joe Bloggs", "Manager");
    Expression exp = parser.parseExpression(
            "{ \"Manager\":\"37.5\", \"Ceo\":\"40\"}[#root.jobTitle]");
    StandardEvaluationContext context = new StandardEvaluationContext(employee);
    context.setRootObject(employee);
    System.out.println(exp.getValue(context, String.class));
}

static class Employee {
    private String firstName;
    private String jobTitle;

    Employee(String firstName, String jobTitle) {
        this.firstName = firstName;
        this.jobTitle = jobTitle;
    }

    public String getJobTitle() {
        return jobTitle;
    }
}

CodePudding user response:

From looking at the SpEL docs it seems like I should be able to reference the attribute directly?

This is correct for below case, both will print "Manager"

System.out.println(parser.parseExpression("#root.jobTitle").getValue(context, String.class));
System.out.println(parser.parseExpression("jobTitle").getValue(context, String.class));

But for expression inside [], the handling is different. Since there is no language specification for SpEL, I can just explain base on the behaviour. When you run

System.out.println(parser.parseExpression(
           "{\"jobTitle\":\"37.5\"}[jobTitle]").getValue(context, String.class));

This will actually print "37.5"([jobTitle] is treated as [\"jobTitle\"]). The author decided to make it easier to access value of Map, and the drawback is you need to specify with #root.jobTitle when referencing the root object.

  •  Tags:  
  • Related