spring-bootmaventhymeleaf

Pagination fragment using servletUriComponentsBuilder within Thymeleaf


I am using Spring boot 3.1.4 with Maven and Java 17, working on Wim Deblauwe's book called #Taming Thymeleaf. I've reached page 249 and I am now trying to implement pagination. Although I managed to successfully display the pagination summary, I've been unable to create the urlBuilder variable at the top of the pagination.html fragment, which is essential to manipulate to URL links so as to feed the pagination buttons:

<div th:fragment="controls" class="bg-white px-4 py-3 flex items-center justify-between border-t border-gray-200 sm:px-6" th:with="urlBuilder=${T(org.springframework.web.servlet.support.ServletUriComponentsBuilder)}">

As soon as I try to include the above line as th:with="urlBuilder=${T(org....)}" to load ServletUriComponentsBuilder, and I rebuild my fragment (npm run build && npm run watch),the Chrome browser hangs. I've got to remove this line, only leave the class attribute and reload the fragment to get back to normal. When I go to the Spring boot stack trace, I notice the following error:

at org.attoparser.MarkupParser.parseDocument(MarkupParser.java:301) ~[attoparser-2.0.7.RELEASE.jar:2.0.7.RELEASE] ... 53 common frames omitted Caused by: org.springframework.expression.EvaluationException: Access is forbidden for type 'org.springframework.web.servlet.support.servleturicomponentsbuilder' in this expression context.

I first looked at pom.xml to check whether I missed any dependencies. My pom.xml is in accordance with Wim Deblauwe's GitHub source code for chapter 10 minus some adaptations of my own: I am using MySQL instead of Postgres, I am neither using jpearl nor flyway. The following dependencies were added to my pom.xml to allow the call to ServletUriComponentsBuilder in the Thymeleaf pagination.html fragment:

    <dependency>
        <groupId>org.thymeleaf.extras</groupId>
        <artifactId>thymeleaf-extras-springsecurity4</artifactId>
        <version>3.0.1.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>6.0.12</version>
    </dependency>
    

These dependencies additions to pom.xml did not help at all. Thanks in advance for helping me find a way to load the ServletUriComponentsBuilder in the pagination.html fragment without any error.

My pagination so far


Solution

  • There has been a change in Thymeleaf 3.1.2 that introduced this unfortunately.

    As a workaround, you can define a wrapper class like this in your own code:

    
    import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
    
    public class ServletUriComponentsBuilderWrapper {
    
      public static ServletUriComponentsBuilder fromCurrentRequest() {
        return ServletUriComponentsBuilder.fromCurrentRequest();
      }
    }
    

    Then replace this:

    th:with="urlBuilder=${T(org.springframework.web.servlet.support.ServletUriComponentsBuilder)}"
    

    with (Suppose you created the class in the com.mycompany.myproject.infrastructure.web package):

    th:with="urlBuilder=${T(com.mycompany.myproject.infrastructure.web.ServletUriComponentsBuilderWrapper)}"
    

    I opened an issue with Thymeleaf but got no further information so far.