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

Spring Boot从Service取数据到Controller展示UI报错求助

Spring Boot数据展示报错修复方案

问题场景

在Spring Boot项目中尝试从Service层读取数据到Controller层,最终在UI展示时出现错误。

错误信息

ERROR 20984 --- [nio-8080-exec-2] s.e.ErrorMvcAutoConfiguration$StaticView : Cannot render error page for request [/countries] as the response has already been committed. As a result, the response may have the wrong status code.

数据库数据

mysql> select * from country;
+----+-------------+------+---------------+---------------+-------------+
| id | capital     | code | continent     | description   | nationality |
+----+-------------+------+---------------+---------------+-------------+
|  1 | Washington  | 01   | North America | United States | American    |
|  2 | Addis Ababa | 01   | Africa        | Ethiopia      | Ethiopian   |
+----+-------------+------+---------------+---------------+-------------+

各层代码

实体类(Model)代码

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Country {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String code;
    private String capital;
    private String description;
    private String nationality;
    private String continent;
    @OneToMany(mappedBy="country")
    private List<State> states;
}

Repository代码

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.kindsonthegenius.FleetApp.models.Country;

@Repository
public interface CountryRepository extends JpaRepository<Country, Integer> {} 

Service代码

@Service
public class CountryService {
    @Autowired
    private CountryRepository countryRepository;

    public List<Country> getCountries(){
        return countryRepository.findAll();
    }
}

Controller代码

@Controller
public class CountryController {
    @Autowired
    private CountryService countryService;

    @GetMapping("/countries")
    public String goCountry(Model model) {
        List<Country> countryList = countryService.getCountries(); 
        model.addAttribute("countries", countryList);
        return "country";
    }
}

UI(Thymeleaf)代码

<table class="table">
            <thead>
              <tr>
                <th scope="col">id</th>
                <th scope="col">Description</th>
                <th scope="col">Capital</th>
               </tr>
            </thead>
            <tbody>
               <tr th:each="country : ${countries}">
                <td th:text="${country.id}"></td>
                <td th:text="${country.description}"></td>
                <td th:text="${country.capital}"></td>
               </tr>
            </tbody>
       </table>

修复步骤

这个错误核心原因是懒加载导致视图渲染时会话已关闭,引发未捕获异常后,Spring尝试渲染错误页面但响应已提交,最终出现冲突。以下是具体修复方案:

  1. 处理懒加载关联问题
    @OneToMany默认是懒加载(FetchType.LAZY),Thymeleaf渲染页面时即使未显式调用states,框架可能会触发关联字段的序列化,此时EntityManager已关闭,抛出LazyInitializationException。

    • 方案一:修改关联为急加载(适合小数据量场景)
      在@OneToMany注解中添加加载策略:
      @OneToMany(mappedBy="country", fetch = FetchType.EAGER)
      private List<State> states;
      
    • 方案二:使用JOIN FETCH提前加载关联数据(性能更优)
      在CountryRepository中添加自定义查询:
      @Repository
      public interface CountryRepository extends JpaRepository<Country, Integer> {
          @Query("SELECT c FROM Country c JOIN FETCH c.states")
          List<Country> findAllWithStates();
      }
      
      然后修改Service层方法:
      public List<Country> getCountries(){
          return countryRepository.findAllWithStates();
      }
      
  2. 验证视图文件位置
    确保country.html视图文件放在src/main/resources/templates/目录下,文件缺失会触发404,也可能引发类似响应提交冲突。

  3. 添加异常捕获
    在Controller层捕获异常,避免未处理的异常导致响应提交后再触发错误页面渲染:

    @Controller
    public class CountryController {
        @Autowired
        private CountryService countryService;
    
        @GetMapping("/countries")
        public String goCountry(Model model) {
            try {
                List<Country> countryList = countryService.getCountries(); 
                model.addAttribute("countries", countryList);
                return "country";
            } catch (Exception e) {
                e.printStackTrace();
                model.addAttribute("error", "加载数据失败");
                return "error"; // 需确保templates目录下有error.html视图
            }
        }
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 07:15:35