Spring SpEL Ternary Operator

Last modified on June 21st, 2015 by Joe.

This Spring tutorial is to explain the ternary operator available in Spring expression language SpEL and learn how to use it by an example Spring application. In Spring 3.0, SpEL introduced a ternary operator to code “If-Then-Else” type conditional checking in Spring expressions. Spring expression language is used to query and manipulate object graph at runtime.

Spring3.0 introduced a new annotation: @Value. We can use this annotation to define SPEL Ternary Operator. We can use @Value annotation at field level, method level or constructor level.Lets take a simple scenario and develop a small Spring Application to learn SpEL Ternary Operator.


SPEL-Ternary-Operation

This is our usual standard syntax for ternary operator. If condition is true, then expression1 is evaluated, otherwise expression2 is evaluated.

Simple Ternary Operator in SpEL Example

Following is a trivial example of using ternary operator in Spring expression language SpEL.

parser.parseExpression("Name").setValue(societyContext, "Royal");
societyContext.setVariable("queryName", "Issac Newton");

expression = "isMember(#queryName)? #queryName + ' is a member of the ' " +
        "+ Name + ' Society' : #queryName + ' is not a member of the ' + Name + ' Society'";

String queryResultString = parser.parseExpression(expression)
        .getValue(societyContext, String.class);

// queryResultString = "Issac Newton is a member of the Royal Society"
		

Spring Ternary Operator Example

This is a complete Spring project example of using ternary operator in SpEL.

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.javapapers.spring4</groupId>
  <artifactId>Spring3.0SPEL</artifactId>
  <version>1.0.0</version>
  
  <properties>
		<spring-framework.version>3.1.2.RELEASE</spring-framework.version>
		<junit.version>4.11</junit.version>
		<cglib.version>3.1</cglib.version>
	</properties>	
	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>		
		<dependency>
			<groupId>cglib</groupId>
			<artifactId>cglib</artifactId>
			<version>${cglib.version}</version>
		</dependency>		
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring-framework.version}</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit.version}</version>
			<scope>test</scope>
		</dependency>
	</dependencies>	
</project>

Create Domain Classes: EmployeeType, EmployeeDetails, and Employee as shown below and to categorize the Employment type of an Employee: either Permanent or Contractor, create an enumEmployeeType as shown below,

package com.javapapers.hrms.emp;

public enum EmployeeType {
	PERMANENT("Permanent"),CONTRACT("Contract");
	
	private String type;
	EmployeeType(String type){
		this.type = type;
	}
	
	@Override
	public String toString(){
		return this.type;
	}
	
	public String getType(){
		return this.type;
	}
}

Create an EmployeeDetails Class which contains employee id and employment type.

package com.javapapers.hrms.emp;

public class EmployeeDetails {

	private int id;
	private EmployeeType empType;
	public EmployeeDetails(int id,EmployeeType empType) {
		this.id = id;
		this.empType = empType;
	}
	
	public int getId() {
		return id;
	}
	public EmployeeType getEmpType() {
		return empType;
	}
	
}

Create an Employee Class. It uses Spring’s @Value annotation with SpEL Ternary operator EmployeeDetails object to calculate bonus.

package com.javapapers.hrms.emp;

import org.springframework.beans.factory.annotation.Value;

public class Employee {

	private int id;
	private String name;
	private double sal;
	@Value("#{employeeDetails.empType.type.equals(\"Permanent\")?10000:1000}")
	private double bonus;
	
	public Employee(int id,String name,double sal) {
		this.id = id;
		this.name = name;
		this.sal = sal;
	}

	public int getId() {
		return id;
	}

	public String getName() {
		return name;
	}

	public double getSal() {
		return sal;
	}

	public double getBonus() {
		return bonus;
	}
		
}
package com.javapapers.hrms.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.javapapers.hrms.emp.Employee;
import com.javapapers.hrms.emp.EmployeeDetails;
import com.javapapers.hrms.emp.EmployeeType;

@Configuration
public class EmployeeConfig {

	@Bean(name="employeeDetails")
	public EmployeeDetails getEmployeeDetails() {
		return new EmployeeDetails(111,EmployeeType.PERMANENT);
	}
	
	@Bean(name="employee")
	public Employee getEmployee() {
		return new Employee(111,"JavaPapers",35000);
	}
}

Create Junit Test class. It uses Spring Test module annotation @ContextConfiguration,

package com.javapapers.hrms.emp;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.junit.Assert.*;
import com.javapapers.hrms.config.EmployeeConfig;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=EmployeeConfig.class)
public class Spring3SPELTest {

	@Autowired
	private ApplicationContext applicationContext;
	  
	  @Test
	  public void test() {
		  Employee emp = (Employee)applicationContext.getBean("employee");
		  assertNotNull(emp);
		  assertTrue(emp.getBonus() == 10000d);
	  }

}

This is how the project looks,

Spring-Ternary-Project

Download the example Spring project Spring3.0SPEL