Spring Expression Language [SpEL]
Expression Language is a programming language, it will provide simplified syntax’s to manipulate Objects and their properties.
E.g
1. JSP EL: To evaluate the objects and their properties like request, session, application etc. and their parameters and attributes.
2. Struts2.x OGNL: To evaluate the objects and their properties like Value Stack, CentralContext, request, application
3. JBOSS EL: To evaluate Objects and their properties which are related to the JBOSS implementations.
4. SpEL: To evaluate bean objects and their properties in Spring applications.
SpEL: It is an Expression Language; it has provided simplified syntax’s to manipulate objects and their properties during Run time of the applications.
To prepare and Evaluate Expressions in SpEL, Spring has provided very good Predefined Library in the form of “org.springframework.exprssion” package.
In Spring applications, if we want to prepare and evaluate expressions, we have to use the following steps.
1. Create ExpressionParser object
ExpressionParser is able to manage expressions and it able to have expression evaluation mechanisms. To represent Expression Parser Spring Framework has provided a predefined interface in the form of org.springframework.expression.ExpressionParser.
For ExpressionParser interface, Spring framework has provided a predefined implementation class in the form of “org.springframework. expression.spel.standard.SpelExpressionParser”.
ExpressionParser parser = new SpelExpressionParser();
Note
ExpressinParser is able to evaluate the expressions by using StandardEvaluationContext, it able to evaluate the expressions against objects by preparing Object Graphs internally.
In SpEL, Expression object is able to represent single Expression. To represent Expression, SpEL has provided a predefined interface in the form of “org.springframework.expression.Exception” . For Expression interface SpEL has provided a predefined implementation class in the form of
"org.springframework.expression.spel.standard.SpelExpression"
To prepare expression and to get Expression object we have to use the following method from ExpressionParser.
public Expression parseExpression(String expression)
E.g.
Expression expr = parser.parseExpression("10+10");
Get Result of the Expression Evaluation
To get expression result we have to use the following method from Expression.
public Object getValue()
E.g.
int val = (Object) expr.getValue();
package com.ashok.spring.core.spel.test; import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; import org.springframework.expression.spel.standard.SpelExpressionParser; /** * * @author ashok.mariyala * */ public class TestExpression { public static void main(String[] args) { ExpressionParser parser = new SpelExpressionParser(); Expression expr = parser.parseExpression("10+10"); int val1 = (Integer) expr.getValue(); System.out.println(val1); expr = parser.parseExpression("10*10"); int val2 = (Integer) expr.getValue(); System.out.println(val2); expr = parser.parseExpression("'abc'+'def'"); String val3 = (String) expr.getValue(); System.out.println(val3); parser = new SpelExpressionParser(); expr = parser.parseExpression("'Welcome SPEL'.concat('!')"); String message = (String) expr.getValue(); System.out.println(message); } }
Output
20 100 abcdef Welcome SPEL!
Using StandardEvaluationContext
package com.ashok.spring.core.spel.beans; /** * * @author ashok.mariyala * */ public class Calculator { private int num1; private int num2; public int getNum1() { return num1; } public void setNum1(int num1) { this.num1 = num1; } public int getNum2() { return num2; } public void setNum2(int num2) { this.num2 = num2; } public int add() { return num1 + num2; } public int sub() { return num1 - num2; } public int mul() { return num1 * num2; } }
package com.ashok.spring.core.spel.test; import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; import com.ashok.spring.core.spel.beans.Calculator; /** * * @author ashok.mariyala * */ public class TestCalculaorExpression { public static void main(String[] args) { Calculator cal = new Calculator(); StandardEvaluationContext context = new StandardEvaluationContext(cal); ExpressionParser parser = new SpelExpressionParser(); Expression expr1 = parser.parseExpression("num1"); expr1.setValue(context, "10"); Expression expr2 = parser.parseExpression("num2"); expr2.setValue(context, "5"); System.out.println("num1 :" + cal.getNum1()); System.out.println("num2 :" + cal.getNum2()); System.out.println("Addition :" + cal.add()); System.out.println("Substraction :" + cal.sub()); System.out.println("Multiplicatin :" + cal.mul()); } }
Output
num1 :10 num2 :5 Addition :15 Substraction :5 Multiplicatin :50
SpEL Features
- Expressions
- Operators
- Variables
- Method Invocations
- Collections
1. Expressions
SpEL is able to allow two types of Expressions.
- Literal Expressions
- Regular Expressions
1. Literal Expressions: It able to allow only literals inside the Expressions.
2. Regular Expressions: It able to check the specified String against the provided Regular Expressions, If the provided String is as per the provided Regular Expression then it will return true value otherwise it will return false value.
To compare String with Regular Expression we have to use “matches” operator, it is a Boolean operator, it will check whether the provided String is satisfying the provided Regular Expression or not.
Syntax:
‘String_Data’ matches ‘Reg_Expression’
E.g
package com.ashok.spring.core.spel.test; import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; import org.springframework.expression.spel.standard.SpelExpressionParser; /** * * @author ashok.mariyala * */ public class TestLiteralAndRegularExpressions { public static void main(String[] args) { ExpressionParser parser = new SpelExpressionParser(); Expression expr = parser.parseExpression("10 + 10"); System.out.println(expr.getValue()); expr = parser.parseExpression("'abc' + 'def'"); System.out.println(expr.getValue()); expr = parser.parseExpression("0xABCDEF*10+6"); System.out.println(expr.getValue()); expr = parser.parseExpression("'Spring' matches 'Sp.*'"); System.out.println(expr.getValue()); expr = parser.parseExpression("'[email protected]' matches '[a-z]*@gmail.com'"); System.out.println(expr.getValue()); expr = parser.parseExpression("'[email protected]' matches '[a-z]*@gmail.com'"); System.out.println(expr.getValue()); } }
Output
20 abcdef 112593756 true true false
2.Operators
In SpEL, to prepare Expressions we are able to use the following operators.
i. Arithmetic Operators
+, -, *, /, % etc.
ii. Logical Operators
and or && or or || not or !
iii. Comparision Operators
eq or == ne or != lt or < le or <= gt or > ge or >=
iv. Ternary Operator
Expr1? Expr2: Expr3;
v. Type Operator[T]
It able to represent a particular class type or interface type in SpEL.
Syntax
T(Class_Name)
vi. Safe Navigation Operator
In general, in JAVA applications, if we access any instance variable or method on a reference variable contains null value then JVM will rise an exception like java.lang.NullPointerException. In SpEL , to avoid NullPointerExceptions we are able to use “Safe Navigation” operator.
Syntax
var_Name?.methid_or_Var_Name()
package com.ashok.spring.core.spel.test; import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; import com.ashok.spring.core.spel.beans.User; /** * * @author ashok.mariyala * */ public class TestOperatorExpressions { public static void main(String[] args)throws Exception { ExpressionParser parser = new SpelExpressionParser(); Expression expr = parser.parseExpression("10 + 20"); System.out.println(expr.getValue()); expr = parser.parseExpression("10 * 20"); System.out.println(expr.getValue()); expr = parser.parseExpression("true and true"); System.out.println(expr.getValue()); expr = parser.parseExpression("true && false"); System.out.println(expr.getValue()); expr = parser.parseExpression("true or true"); System.out.println(expr.getValue()); expr = parser.parseExpression("true || false"); System.out.println(expr.getValue()); expr = parser.parseExpression("10 ne 20"); System.out.println(expr.getValue()); expr = parser.parseExpression("10 >= 20"); System.out.println(expr.getValue()); expr = parser.parseExpression("10 lt 5"); System.out.println(expr.getValue()); expr = parser.parseExpression("10 ge 5"); System.out.println(expr.getValue()); expr = parser.parseExpression("10 eq 10? 'condition is true': 'condition is false'"); System.out.println(expr.getValue()); expr = parser.parseExpression("T(Thread).MIN_PRIORITY"); System.out.println(expr.getValue()); expr = parser.parseExpression("T(Integer).toString(10)"); System.out.println(expr.getValue()); User user = new User(); StandardEvaluationContext context = new StandardEvaluationContext(user); expr = parser.parseExpression("uname?.toUpperCase()"); System.out.println(expr.getValue(context)); } }
Output
30 200 true false true true true false false true condition is true 1 10 null
3. Variables
In SpEL, if we want to access any variable which is already existed in StandardEvaluationContext then we have to use the following syntax.
#var_Name
If we want to set variable to StandardEvaluationContext then we have to use the following method.
public void setVariable(String var_Name, Object val)
E.g
package com.ashok.spring.core.spel.test; import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; import com.ashok.spring.core.spel.beans.Calculator; /** * * @author ashok.mariyala * */ public class TestVariableExpressions { public static void main(String[] args) { Calculator cal = new Calculator(); StandardEvaluationContext context = new StandardEvaluationContext(cal); context.setVariable("number1", 10); context.setVariable("number2", 5); ExpressionParser parser = new SpelExpressionParser(); Expression expr1 = parser.parseExpression("num1 = #number1"); Expression expr2 = parser.parseExpression("num2 = #number2"); System.out.println(expr1.getValue(context)); System.out.println(expr2.getValue(context)); System.out.println(cal.add()); System.out.println(cal.sub()); System.out.println(cal.mul()); } }
Output
10 5 15 5 50
4. Method Invocations
In SpEL , we are able to declare methods and we are able to access that methods as per the requirement. If we want to declare a user defined method and if we want to access user defined method through an expression then we have to use the following steps.
- Create StandardEvaluationContext object.
- Register Method with a name.
public void registerFunction(String meth_Name, Method m)
- Prepare an Expression with method call and access it.
E.g
package com.ashok.spring.core.spel.beans; /** * * @author ashok.mariyala * */ public class ReverseString { public static void reverseString(String str) { StringBuffer sb = new StringBuffer(str); System.out.println(sb.reverse()); } }
package com.ashok.spring.core.spel.test; import java.lang.reflect.Method; import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; /** * * @author ashok.mariyala * */ public class TestMethodInvocation { public static void main(String[] args)throws Exception { StandardEvaluationContext context = new StandardEvaluationContext(); Class cls = Class.forName("com.ashok.spring.core.spel.beans.ReverseString"); Method method = cls.getDeclaredMethod("reverseString", String.class); context.registerFunction("reverse", method); context.setVariable("str", "Ashok Kumar"); ExpressionParser parser = new SpelExpressionParser(); Expression expr = parser.parseExpression("#reverse(#str)"); expr.getValue(context); // Accessing Predefined methods expr = parser.parseExpression("new java.util.Date().toString()"); System.out.println(expr.getValue()); expr = parser.parseExpression("'Ashok Kumar'.toUpperCase()"); System.out.println(expr.getValue()); } }
Output
ramuK kohsA Thu Mar 14 08:39:34 IST 2019 ASHOK KUMAR
5. Collections
In SpEL, we are able to declare Collections and we are able to access the content from Collection objects by using the following Expression Syntax.
Collection_Ref_Var.?Condition_Expression
E.g
package com.ashok.spring.core.spel.beans; /** * * @author ashok.mariyala * */ public class CityState { private String city; private String state; public CityState(String city, String state) { this.city = city; this.state = state; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getState() { return state; } public void setState(String state) { this.state = state; } @Override public String toString() { return "CityState [city=" + city + ", state=" + state + "]"; } }
package com.ashok.spring.core.spel.beans; import java.util.ArrayList; import java.util.List; public class CityStateCollection { private List<CityState> cityState = new ArrayList<>(); public List<CityState> getCityState() { cityState.add(new CityState("Hyderabad", "Telangana")); cityState.add(new CityState("Vijayawada", "Andhrapradesh")); cityState.add(new CityState("Warangal", "Telangana")); cityState.add(new CityState("Vizag", "Andhrapradesh")); cityState.add(new CityState("Medak", "Telangana")); return cityState; } }
package com.ashok.spring.core.spel.test; import java.util.List; import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; import com.ashok.spring.core.spel.beans.CityState; import com.ashok.spring.core.spel.beans.CityStateCollection; /** * * @author ashok.mariyala * */ @SuppressWarnings("unchecked") public class TestCollectionExpression { public static void main(String[] args) { CityStateCollection collection = new CityStateCollection(); StandardEvaluationContext context = new StandardEvaluationContext(collection); ExpressionParser parser = new SpelExpressionParser(); Expression expr = parser.parseExpression("cityState.?[state == 'Andhrapradesh']"); List<CityState> list = (List<CityState>) expr.getValue(context); System.out.println(list); } }
Output
[CityState [city=Vijayawada, state=Andhrapradesh], CityState [city=Vizag, state=Andhrapradesh]]