teekay
teekay

Reputation: 323

spring boot / thymeleaf nested loop object access

I am using Spring Boot and Thymeleaf to create a single landing page for my application. For this, I need to render a List of Host objects that all contain a Container. Here is the relevant code:

public class Container {
    private String name;
    private String baseUrl;
    private String status;

    public Container(String name, String baseUrl, String status) {
        this.name = name;
        this.baseUrl = baseUrl;
        this.status = status;
    }

    public String getName() { return name; }
    public String getBaseUrl() { return baseUrl; }
    public String getStatus() { return status; }
}

public class Host {
    private HashMap<String, Container> containers;
    ....
    public List<Container> getContainers() {
         return containers.values();
    }
}

@RequestMapping("/")
public class IndexController {
      @RequestMapping("/")
      public String getIndex(Model model) {
          model.addAttribute("hosts", hostRepository.getAllServers());
          return "index";
      }
}

Now I want to iterate over all servers and display the information about each Container in a table. My Thymeleaf template looks like this:

<div class="panel panel-default" th:each="host : ${hosts}">
            <div class="panel-heading">
                <b th:text="${host.name}">Host X</b>
                <div class="panel-body">
                    <table class="table">
                        <thead>
                            <tr>
                                <th>Name</th>
                                <th>URL</th>
                                <th>Status</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr th:each="container : ${host.getContainers()}">
           <!-- HERE IS THE PROBLEM -->
                                <td th:text="${container.name}">Service1</td>
                                <td th:text="${container.baseUrl}">domain.com/api/url</td>
                                <td th:text="${container.status}">RUNNING</td>
           <!-- HERE ENDS THE PROBLEM -->
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>
</div>

My problem is the part where is access the container's properties (marked by the commentary). Every time I get a SpringEL Exception. If I remove the th:text="${container.xy}" and replaces it with th:text="${container} a String version of the container is shown so I have access to the object and the loop it working properly. I also tried to replace the field access with getters (e.g. getStatus()) but it also does not work.

Thanks for your help. If you need more information, feel free to ask.

Setup:

edit: The exception thrown is: nested exception is org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "container.name" (index:35) where index:35 is the first problematic line.

The toString() output when using ${container} is jenkins=com.my.app.Container@7552c269 and jenkins is the name attribute of the Container instance.

Solution It seemed that the nested loop was iterating over a Map instead of a List. Changing ${container.xy} to ${container.getValue().xy} solved the problem.

Upvotes: 0

Views: 1257

Answers (1)

teekay
teekay

Reputation: 323

Solution

It seemes that the nested loop was iterating over a org.thymeleaf.util.EvaluationUtil$MapEntry instead of a List. Changing ${container.xy} to ${container.getValue().xy} solved the problem.

Bits learned along the way:

  • Override the toString() method to obtain formatted information about the object iterating over. In this case the output was key=value which altough value was expected. This gave a hint that the current object must be something else than a Container instance
  • Look at the stack trace of Thymeleaf (usually its a hint that something is null or not public)
  • Use getClass() on the current object during the iteration to check if something went wrong here

Upvotes: 2

Related Questions