En este artículo se revisan algunas características más avanzadas que permitir escribir expresiones más complejas con SpEL.
Variables
Cuando se utiliza directamente una instancia del parser de expresiones se pueden definir variables, y luego hacer referencia a ellas usando la nomenclatura de almohadilla:
context.setVariable("alias", "Clark Kent"); parser.parseExpression("nombre=#alias").getValue(context);
Existen dos variables especiales llamadas #root
y #this
. La primera hace referencia siempre al objeto contextual sobre el que aplica la expresión siendo evaluada. La segunda toma el valor del objeto siendo evaluado.
Funciones
Cuando se utiliza directamente una instancia del parser de expresiones se pueden definir funciones, y luego hacer referencia a ellas usando la nomenclatura de almohadilla:
context.registerFunction("reverse", StringUtils.class.getDeclaredMethod("reverse", new Class[]{String.class})); parser.parseExpression("#reverse('monja')").getValue(context);
Beans
Cuando se utiliza directamente una instancia del parser de expresiones se pueden hacer referencia a beans utilizando una instancia de la interface BeanResolver
, y utilizando la nomenclatura de arroba:
BeanResolver resolver = new BeanFactoryResolver(applicationContext); context.setBeanResolver(resolver); parser.parseExpression("@fooBean").getValue(context);
if-then-else
Se puede utilizar el operador ternario if-then-else
de la forma habitual:
#{ 1 == 1 ? 'churra' : 'merina' } #{ 'abc' instanceof T(int) ? 'entero' : 'desconocido' }
Elvis
El operador Elvis (?:
) es una forma abreviada del operador ternario anterior. Permite omitir una expresión resultado si esta es igual a la condición. Se entiende mejor con un ejemplo.
Esta expresión:
valor != null ? valor : 'error'
Es igual a la siguiente utilizando el operador Elvis:
valor?:'error'
La documentación oficial comenta que el operador proviene del lenguaje Groovy, y que su nombre deriva del hecho de que ?:
asemeja a un emoticon con el típico tupé de Elvis Presley.
Safe Navigation
El operador Safe Navigation (?.
) evita que se eleve una excepción de tipo NullPointerException
cuando se intenta acceder a una propiedad sobre un objeto nulo. Si el objeto es nulo el operador retorna directamente nulo en vez de intentar acceder a la propiedad:
#{ biblioteca?.libros }
Este operador también proviene también de Groovy.
Collection Selection
El operador Collection Selection (?[<expression>]
) permite filtrar elementos de una colección retornando sólo las que cumplan una determinada condición:
#{ ovejas.?[tipo == 'merina'] }
Collection Projection
El operador Collection Projection(![<expression>]
) permite construir una colección de objetos de un tipo distinto a los originales de una colección dada.
Por ejemplo, se puede partir de una lista de libros y obtener una lista de autores:
#{ ovejas.![autor] }
Templates
Dentro de las expresiones se pueden utilizar otras expresiones que tienen que ser evaluadas para obtener su valor usando la clase TemplateParserContext
:
parser.parseExpression("Número ganador: #{ T(java.lang.Math).random() }", new TemplateParserContext() ).getValue(String.class);