Thymeleaf页面无法展示Transaction实体分组数据问题排查
解决交易分组数据在Thymeleaf页面不显示的问题
让我们一步步排查并修复你遇到的问题——交易能成功保存但页面空白,核心问题出在分组逻辑缺失、无效的方法调用、Model数据未传递以及模板变量错误这几个方面:
1. 修复TransactionGroup类的无效方法
你写的setTransactions重载方法完全没有给transactions列表赋值,相当于空操作。我们需要初始化列表并添加有效的添加交易方法:
public class TransactionGroup { private LocalDate date; // 初始化空列表,避免NullPointerException private List<Transaction> transactions = new ArrayList<>(); // 保留原有的getter和setter public LocalDate getDate() { return date; } public void setDate(LocalDate date) { this.date = date; } public List<Transaction> getTransactions() { return transactions; } public void setTransactions(List<Transaction> transactions) { this.transactions = transactions; } // 添加一个有效的添加交易方法,替代原来的无效重载 public void addTransaction(Transaction transaction) { this.transactions.add(transaction); } }
2. 在页面展示方法中实现按日期分组逻辑
你当前的saveIncome方法里创建TransactionGroup的代码毫无意义——分组逻辑应该在展示交易列表的Controller方法中完成,而不是保存的时候。假设你跳转到的/api/wallet/userWallet/balance/{userId}对应的Controller方法如下,添加分组逻辑:
@GetMapping("/api/wallet/userWallet/balance/{userId}") public String showUserBalance(@PathVariable long userId, Model model) { // 1. 获取该用户的所有交易记录 List<Transaction> userTransactions = transactionService.getTransactionsByUserId(userId); // 2. 按日期分组,转换成TransactionGroup列表 List<TransactionGroup> transactionGroups = userTransactions.stream() .collect(Collectors.groupingBy(Transaction::getDate)) // 按交易日期分组 .entrySet().stream() .map(entry -> { TransactionGroup group = new TransactionGroup(); group.setDate(entry.getKey()); group.setTransactions(entry.getValue()); // 把同日期的交易放入分组 return group; }) .sorted(Comparator.comparing(TransactionGroup::getDate).reversed()) // 按日期倒序显示(最新的在前) .collect(Collectors.toList()); // 3. 把分组后的数据放入Model,传给Thymeleaf页面 model.addAttribute("transactionGroups", transactionGroups); // 这里可以添加其他需要的属性,比如用户钱包余额等 return "balance_page"; // 替换成你实际的页面模板名称 }
3. 清理saveIncome方法中的无效代码
删除saveIncome里调用无效setTransactions的代码,因为分组逻辑已经移到展示页面的方法中了:
@PostMapping("/saveIncome/{walletId}") public String saveIncome(@PathVariable(value = "walletId") long walletId, @Valid Transaction transaction, BindingResult result, Model model) { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); UserDetailsImpl user = (UserDetailsImpl) authentication.getPrincipal(); long userId = user.getId(); Wallet wallet = walletService.getWalletById(walletId); boolean thereAreErrors = result.hasErrors(); if (thereAreErrors) { model.addAttribute("incomeCategories", IncomeCategories.values()); return "income_transaction"; } transaction.setWallet(wallet); transaction.setUserId(userId); transaction.setWalletName(wallet.getWalletName()); // 删掉这行无效代码: // transactionGroup.setTransactions(transaction.getWalletName(), transaction.getAmount(), transaction.getNote(), transaction.getDate(), transaction.getTransactionType(), transaction.getExpenseCategories(), transaction.getIncomeCategories()); transactionService.saveIncome(transaction, walletId, userId); return "redirect:/api/wallet/userWallet/balance/" + userId; }
4. 修复Thymeleaf模板的变量错误
你的模板里有两个关键错误:
- 循环的变量应该是
transactionGroups(我们放入Model的分组列表),而不是单个transactionGroup - 内部循环的变量是
transaction,引用属性时应该用${transaction.amount}而不是${transactions.amount}(复数形式错误)
修改后的模板代码:
<div th:each="group : ${transactionGroups}"> <h1 th:text="${#temporals.format(group.date, 'yyyy-MM-dd')}"></h1> <div th:each="transaction : ${group.transactions}"> <h2>Amount: <span th:text="${transaction.amount}"></span></h2><br> <h2>Note: <span th:text="${transaction.note} ?: 'No note'"></span></h2><br> <h2>Wallet name: <span th:text="${transaction.walletName}"></span></h2><br> <!-- 根据交易类型显示对应分类,避免显示null --> <h2 th:if="${transaction.transactionType == 'EXPENSE'}">Expense Category: <span th:text="${transaction.expenseCategories}"></span></h2><br> <h2 th:if="${transaction.transactionType == 'INCOME'}">Income Category: <span th:text="${transaction.incomeCategories}"></span></h2> <hr> </div> </div>
最后需要检查的点
- 确保
transactionService.getTransactionsByUserId(userId)能正确查询到该用户的所有交易记录 - 确认交易的
date字段在保存时已经被正确赋值(比如前端表单传递了正确的日期,或者后端默认设置为LocalDate.now()) - 检查Thymeleaf模板的路径是否正确,跳转的页面是否是你修改的这个模板
内容的提问来源于stack exchange,提问作者Frosty Nah
相关产品推荐
相关产品推荐

