You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot+Thymeleaf同代码不同输出:嵌套循环渲染异常求助

嘿,这个问题确实有点诡异,不过咱们一步步拆解来看——先给你吃个定心丸:Thymeleaf的循环(包括嵌套循环)根本不需要额外依赖,只要你已经引入了Spring Boot的Thymeleaf starter,所有循环、表达式相关的功能都是开箱即用的,所以依赖配置肯定不是问题根源。

接下来咱们重点排查你这个“两个启动类导致渲染差异”的核心矛盾:

最可能的原因:Spring Boot组件扫描范围不匹配

Spring Boot默认只会扫描启动类所在包及其子包下的所有组件(控制器、服务、Repository等等)。如果你的两个带main方法的启动类在不同的包路径下,而你的控制器又不在对应启动类的扫描范围内,那问题就来了:

  • 比如启动类A在com.myproject.app1,控制器在com.myproject.controller(和app1平级),那启动A时,Spring根本找不到你的控制器,会用默认的映射或者干脆没有处理/请求的控制器,自然不会往Model里放myList,Thymeleaf找不到变量就不会生成列表项。
  • 而另一个启动类B可能刚好和控制器在同一个根包下(比如都在com.myproject),所以能正常扫描到控制器,渲染就正常。

其次要排查:模型数据是否正确传递

如果两个启动类都能扫描到控制器,但其中一个控制器的逻辑有问题:

  • 比如启动类对应的控制器没有初始化myList,或者在处理GET请求时没有把myList放入Model中;
  • 或者myList本身是空集合,Thymeleaf遇到空集合时,th:each会直接跳过,不会生成任何<li>元素,就会出现你看到的空<ol>。

快速排查步骤

  1. 检查启动类的包与扫描范围
    打开那个有问题的启动类,看看它的@SpringBootApplication注解:

    • 如果控制器在不同的包,你需要手动指定扫描范围,比如:
      @SpringBootApplication(scanBasePackages = "com.myproject")
      
    • 最稳妥的方式是把所有启动类都放在项目的根包下(比如com.myproject),这样Spring会自动扫描所有子包的组件。
  2. 验证控制器是否被加载
    启动有问题的应用,查看控制台日志,找类似这样的输出:

    Mapped "{[/],methods=[GET]}" onto public String com.myproject.controller.xxxController.index(...)
    

    如果没有这条日志,说明控制器根本没被Spring注册,就是扫描范围的问题。

  3. 确认Model数据是否存在
    在控制器的处理方法里加一行日志,输出myList的状态:

    System.out.println("当前myList的内容:" + myList);
    

    启动应用后,访问页面并提交请求,看看控制台输出的myList是不是空的,或者有没有正确添加内容。

  4. 检查启动类的注解差异
    对比两个启动类的注解,看看有没有其中一个加了@ComponentScan、@EnableAutoConfiguration等特殊配置,导致扫描范围或bean加载逻辑不同。

最后再强调一遍:Thymeleaf的循环功能不需要额外依赖,你的pom.xml里只要有下面这一段就够了:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

按照上面的步骤排查,应该能很快找到问题所在!

内容的提问来源于stack exchange,提问作者Moe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:50:00