Thymeleaf vs. SpEL vs. OGNL

26 Nov 2021

This is a follow-up to the recent article: Thymeleaf - An Expression of Surprise.

Thymeleaf's Use of OGNL

Thymeleaf’s standard variable expression syntax is ${ ... }. The contents inside this expression (the ... inside the curly brackets) form an OGNL (Object Graph Navigation Library) expression - and you can read about its syntax in the OGNL language guide.

It is worth familiarizing yourself with OGNL. You can use OGNL expressions in Thymeleaf in ways which may be less familiar to you. For example, suppose you have a Java Map:

Java
1
2
3
Map<String, String> data = new HashMap<>();
data.put("foo", "bar");
data.put("baz", "bat");

You can access an entry in this map using an OGNL expression such as:

HTML
1
2
<!-- produces: <div>bar</div> -->
<div th:text="${data['foo']}"></div>

This is OGNL’s equivalent to Java’s data.get("foo"). The square brackets may suggest this is an array access operation - but it works correctly with our Map.

You can also use syntax such as:

HTML
1
2
3
4
5
<!-- access the map's keys -->
<div th:text="${data.keys}"></div>

<!-- access the map's values -->
<div th:text="${data.values}"></div>

Another example - in this case showing some basic OGNL arithmetic:

HTML
1
2
<!-- produces: <div>3</div> -->
<div th:text="${1 + 2}"></div>

Thymeleaf vs. OGNL

That last basic arithmetic example could have been written as follows:

HTML
1
2
<!-- produces: <div>3</div> -->
<div th:text="${1} + ${2}"></div>

In this case you get the same output, but now we have two OGNL expressions and the + operator which is not part of any OGNL expression. In this case, performing the addition is the responsibility of Thymeleaf, not OGNL.

This makes the point that Thymeleaf has its own operators, separate from (but often exactly the same as) the OGNL equivalents. Addition is addition, in both OGNL and Thymeleaf.

Thymeleaf, Spring and SpEL

All of the examples in the previous sections were for the Thymeleaf standard dialect.

If you are building an application using the Spring framework, however, you will by default be using the SpringStandard Dialect instead.

You can read about that here.

More fundamentally, you will no longer be using OGNL. Instead, you will be using SpEL - the Spring Expression Language.

SpEL offers several enhancements which are not available in OGNL - and therefore not available in the Thymeleaf standard dialect. For example, it has the safe navigation operator, which provides a convenient way to handle null values when evaluating expressions.

OGNL vs. SpEL

You may occasionally find some (potentially surprising) differences between OGNL on the one hand and standard Thymeleaf & SpEL on the other.

Here is one somewhat contrived example, but it shows an important difference:

Pure Thymeleaf, no SpEL:

HTML
1
2
3
4
5
6
<!-- org.thymeleaf.exceptions.TemplateProcessingException:
     Cannot execute subtraction: operands are "null" and "null" -->
<div th:text="${null} - ${null}"></div>

<!-- This is OGNL: <div>0</div> -->
<div th:text="${null - null}"></div>

Thymeleaf with SpEL:

HTML
1
2
3
4
5
6
7
<!-- org.thymeleaf.exceptions.TemplateProcessingException:
     Cannot execute subtraction: operands are "null" and "null" -->
<div th:text="${null} - ${null}"></div>

<!-- org.springframework.expression.spel.SpelEvaluationException:
     EL1030E: The operator 'SUBTRACT' is not supported between objects of type 'null' and 'null' -->
<div th:text="${null - null}"></div>

The problem here is that the OGNL expression (surprisingly) evaluates to 0, whereas the Thymeleaf standard expression and the SpEL expression both throw an error - which is the more expected result, when you try to perform arithmetic on a null value.