所以实际上我有一个控制器,显示表单给用户。用户得到的表单,例如,如果他输入了错误的数据,例如金额字段只是正数,但用户插入-1用户将在屏幕上得到错误消息,但当用户改变该值,并输入例如3金额和提交表单,用户得到404 Whitelabel Error Page
。
第一个网址是:http://localhost:8080/api/transaction/expenseTransaction/4
,现在,用户输入金额-1并单击提交,URL为http://localhost:8080/api/transaction/saveExpense/4
,因此,是否有任何方法可以停留在同一页面上,并允许用户在正确插入数据后保存表单?
我有这个控制器显示窗体:
@GetMapping("/expenseTransaction/{id}")
public String expenseTransaction(@PathVariable(value = "id") long id, Transaction transaction, Model model) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
UserDetailsImpl user = (UserDetailsImpl) authentication.getPrincipal();
long userId = user.getId();
model.addAttribute("userId", userId);
model.addAttribute("transaction", transaction);
model.addAttribute("expenseCategories", ExpenseCategories.values());
return "expense_transaction";
}
这是一种形式:
<div class="container my-5">
<h3> Expense transaction</h3>
<div class="card">
<div class="card-body">
<div class="col-md-8">
<form action="#"
th:action="@{/api/transaction/saveExpense/{walletId} (walletId=${id})}"
th:object="${transaction}" method="post">
<div class="row">
<div class="form-group col-md-6">
<label for="amount" class="col-form-label">Amount</label> <input
type="text" th:field="*{amount}" class="form-control" id="amount"
placeholder="amount"> <span
th:if="${#fields.hasErrors('amount')}" th:errors="*{amount}"
class="text-danger"></span>
</div>
<div class="form-group col-md-8">
<label for="note" class="col-form-label">Note</label> <input
type="text" th:field="*{note}" class="form-control" id="note"
placeholder="note"> <span
th:if="${#fields.hasErrors('note')}" th:errors="*{note}"
class="text-danger"></span>
</div>
<div class="form-group col-md-8">
<label for="date" class="col-form-label">Date</label> <input
type="date" th:field="*{date}" class="form-control"
id="date" placeholder="date"> <span
th:if="${#fields.hasErrors('date')}" th:errors="date"
class="text-danger"></span>
</div>
<div class="form-group col-md-8">
<label for="date" class="col-form-label">Category</label>
<select th:field="${transaction.expenseCategories}">
<option value="0">Select expense category</option>
<option
th:each="expenseCategories : ${expenseCategories}"
th:value="${expenseCategories}"
th:text="${expenseCategories.displayName}"
></option>
</select>
</div>
<div class="form-group col-md-8">
<input type="submit" class="btn btn-primary"
value="Update Student">
</div>
</div>
</form>
</div>
</div>
</div>
这是保存该表单的控制器:
@PostMapping("/saveExpense/{walletId}")
public String saveExpense(@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) {
transaction.setId(walletId);
model.addAttribute("expenseCategories", ExpenseCategories.values());
return "expense_transaction";
}
transaction.setWallet(wallet);
transactionService.saveExpense(transaction, walletId, userId);
return "redirect:/api/wallet/userWallet/balance/" + userId;
}
1条答案
按热度按时间9udxz4iz1#
问题出在你的代码上。
get方法是用
@GetMapping("/expenseTransaction/{id}")
定义的,POST方法是用@PostMapping("/saveExpense/{walletId}")
定义的。GET方法将在模型中公开一个名为
id
的变量,并用路径变量的值填充该变量。POST方法将在模型中公开一个名为
walletId
的变量,并用路径变量的值填充该变量。在你的
th:action
中,你期望id
被填充,这对于GET是真的,而对于POST是真的,因为名称是不同的。要么修正路径变量名,要么在POST方法中使用
walletId
中的值显式地将id
添加到模型中。