英文:
User cant have a second chance for input if first time enter wrong data
问题
以下是你要的代码部分的中文翻译:
// 控制器用于显示表单
@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>费用交易</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">金额</label>
<input type="text" th:field="*{amount}" class="form-control" id="amount" placeholder="金额">
<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">备注</label>
<input type="text" th:field="*{note}" class="form-control" id="note" placeholder="备注">
<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">日期</label>
<input type="date" th:field="*{date}" class="form-control" id="date" placeholder="日期">
<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">类别</label>
<select th:field="${transaction.expenseCategories}">
<option value="0">选择费用类别</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="更新学生">
</div>
</div>
</form>
</div>
</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;
}
如果你需要更多帮助,请随时告诉我。
英文:
So actually I have an controller that show form to user. User get that form and for example if he enter a wrong data, for example amount field is just positive numbers but user insert -1 user will get error message on screen, but when user change that value and enter for example 3 for amount and submit form, user get 404 Whitelabel Error Page
.
So first URL is:
http://localhost:8080/api/transaction/expenseTransaction/4
, now, user enter -1 for amount and click submit, URL is http://localhost:8080/api/transaction/saveExpense/4
, so is there any way to stay on same page and allow user to save form after he insert properly data?
I have this controller to show form:
@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";
}
This is the form:
<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>
</div>
This is controller to save that form:
@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
得分: 1
问题出在你的代码上。
你的GET方法定义为@GetMapping("/expenseTransaction/{id}")
,而你的POST方法定义为@PostMapping("/saveExpense/{walletId}")
。
GET方法将在你的模型中暴露一个名为id
的变量,并将其填充为路径变量的值。
POST方法将在你的模型中暴露一个名为walletId
的变量,并将其填充为路径变量的值。
在你的th:action
中,你期望id
被填充。这对于GET方法是正确的,但对于POST方法是错误的,因为名称不同。
要么修复你的路径变量名称,要么在POST方法中明确地将id
添加到模型中,并使用walletId
的值填充它。
英文:
The problem is your code.
Your get method is defined with @GetMapping("/expenseTransaction/{id}")
and your POST method is defined with @PostMapping("/saveExpense/{walletId}")
.
The GET method will expose a variable named id
in your model and fill that with the value of the path variable.
Your POST method will expose a variable named walletId
in your model and fill that with the value of the path variable.
In your th:action
you expect the id
to be filled. Which is true for the GET not for the POST because the names are different.
Either fix your path variable names, or explicitly add id
to the model in the POST method with the value from walletId
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论