Spring Expression Language [SpEL]
In this tutorial, we are going to discuss Spring Expression Language. Spring Expression Language, usually referred to as SpEL, is one of the modules available under Spring’s Core Module. As the name suggests, it is a powerful expression language mainly used in Spring Framework for evaluating expressions such as Mathematical, Relational & Logical Operations, Conditional & Regular Expressions, etc., at runtime.
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 a very good Predefined Library in the “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 can manage expressions, and it can have expression evaluation mechanisms. To represent Expression Parser, Spring Framework has provided a predefined interface in the form of org.springframework.expression.ExpressionParser.
For the 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 can evaluate the expressions by using StandardEvaluationContext, and it was 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.Expression” . 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 can check the specified String against the provided Regular Expressions. If the provided String is as per the provided Regular Expression, it will return the true value; otherwise, it will return a false value.
To compare String with Regular Expression, we have to use the “matches” operator, a Boolean operator, which will check whether the provided String satisfies 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("'abc@gmail.com' matches '[a-z]*@gmail.com'");
System.out.println(expr.getValue());
expr = parser.parseExpression("'abc@yahoo.com' 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 that contains a null value, then JVM will raise an exception like java.lang.NullPointerException. In SpEL, to avoid NullPointerExceptions, we can use the “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 can declare methods, and we can access those methods as per the requirement. If we want to declare a user-defined method and if we’re going to access the 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]]