Search code examples
javahtmlthymeleaf

Handling Integers as Strings in Thymeleaf Arrays and Lists


Why do the following Thymeleaf th:if tests fail for the strings "0", "1", and "9"?

I have a Java array as follows:

String[] arrayData = {"x", "-1", "0", "1", "9", "10", "11"};

The "x" is included to clarify that this array can contain alphabetic values as well as numeric values.

I have a Thymeleaf template containing the following:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <title>Test</title>
        <meta charset="UTF-8">
    </head>

    <body>
        
        <div th:if="${#arrays.contains(arrayData, '-1')}"
             th:text="'found array string \'-1\''"></div>
                
        <div th:if="${#arrays.contains(arrayData, '0')}"
             th:text="'found array string \'0\''"></div>
                
        <div th:if="${#arrays.contains(arrayData, '1')}"
             th:text="'found array string \'1\''"></div>
                
        <div th:if="${#arrays.contains(arrayData, '9')}"
             th:text="'found array string \'9\''"></div>
        
        <div th:if="${#arrays.contains(arrayData, '10')}"
             th:text="'found array string \'10\''"></div>
        
        <div th:if="${#arrays.contains(arrayData, '11')}"
             th:text="'found array string \'11\''"></div>
                
    </body>

</html>

I expect this to generate the following output in a browser:

found array string '-1'
found array string '0'
found array string '1'
found array string '9'
found array string '10'
found array string '11'

But I actually get the following:

found array string '-1'
found array string '10'
found array string '11'

Question: Why do the tests fail for the strings "0", "1", and "9"? What am I doing wrong?

All such tests for the ten string values "0" through "9" fail. Anything outside that range works as expected.

The same thing happens if I use an ArrayList<String>, with the Thymeleaf #lists.contains() operator.

The Thymeleaf version is:

<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf</artifactId>
    <version>3.0.11.RELEASE</version>
</dependency>

As far as I can tell, I think the Thymeleaf code which implements the #arrays.contains() function is here - and it looks straightforward.

My Java version is AdoptOpenJDK 14.

I am not using Spring in this specific scenario.


Update, After Answer was Provided

If I test with any single character (e.g. x) the same problem happens as with 0 through 9. So the title is somewhat misleading in that regard.


Solution

  • I suspect that if you aren't using Spring, Thymeleaf expressions are being interpreted using OGNL insteald of SPeL -- which appears to treat single character constants as type char instead of type String and so the #arrays.contains expressions fail to match.

    I don't have a setup to test OGNL, but according to this post, this should work:

    <div th:text="${#arrays.contains(arrayData, &quot;0&quot;)}" />
    

    (Or maybe #arrays.contains(arrayData, '' + '0') would work?)