Search code examples
javascriptjavaspringspring-el

Modify rootObject from within a Spring expression


Is it possible to use SpEL to modify the provided rootObject from within the expression?

Consider the following code to see what I mean:

Pojo:

public class Person {

    private int     age;
    private boolean mature;

    // getters and setters omitted for brevity
}

Expression:

Person person = new Person();
person.setAge(18);

SpelParserConfiguration config = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, this.getClass().getClassLoader());
ExpressionParser parser = new SpelExpressionParser(config);
Expression ex = parser.parseExpression("age >= 18");
boolean result = ex.getValue(person, Boolean.class);

See below what I want to do. Is that possible?

ex = parser.parseExpression("if (age >= 18) {mature = true}");
// person now has mature == true

Edit:

Instead of SpEL it is possible to use javax.script, which supports JavaScript and is included in the JVM. Here an example:

ScriptEngineManager manager = new ScriptEngineManager(); 
ScriptEngine jsEngine = manager.getEngineByName("JavaScript");

Person person = new Person();
person.setAge(18);

jsEngine.put("person", person);

jsEngine.eval("if (person.getAge() >= 18) { person.setMature(true); }");

// Calling person.isMature() in Java will now return `true`.

Solution

  • No you would get next an exception SpelParseException with the next message error After parsing a valid expression, there is still more data in the expression.

    You may do it as two next options:

    With a ternary Operator:

    SpelParserConfiguration config = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, this.getClass().getClassLoader());
    ExpressionParser parser = new SpelExpressionParser(config);
    
    Boolean parsedValue = parser.parseExpression("age >= 18 ? Mature=true : Mature=false").getValue(person, Boolean.class);
    
    System.out.println(person.getMature()); // Output = true
    System.out.println(parsedValue); //Output = true
    

    With two spEL expressions:

    SpelParserConfiguration config = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, this.getClass().getClassLoader());
    ExpressionParser parser = new SpelExpressionParser(config);
    Expression ex = parser.parseExpression("age >= 18");
    boolean result = ex.getValue(person, Boolean.class);
    
    if(result)
       parser.parseExpression("mature").setValue(person, "true");
    
    System.out.println(person.getMature()); //Output = true