Issue
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;
}
}
Solution
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.
Answered By - samabcde
Answer Checked By - Senaida (JavaFixing Volunteer)