我在一个项目中使用Spring boot和thymleaf。我有一个由文本字段、下拉菜单和文件输入字段组成的表单。下拉菜单由我在视图的getcontroller中发送的模型填充。当我为返回用户到同一页面并显示错误消息的字段添加验证时,下拉框中的所有值都消失了,文件也不在那里了。在验证失败后,我如何保持下拉菜单填充。
控制器:
@GetMapping("/makeLog")
public String makeLog(Model model) {
if (!securityService.isAuthenticated()) {
return "redirect:/login";
}
model.addAttribute("waters", waterService.findAll());
model.addAttribute("logForm", new FishJournal());
model.addAttribute("baits", baitService.findAll());
return "makeLog";
}
@PostMapping("/makeLog")
public String makeLog(@ModelAttribute("logForm") FishJournal logForm,
@RequestParam("image") MultipartFile multipartFile, BindingResult bindingResult)throws IOException { {
journalValidator.validate(logForm, bindingResult);
if(!multipartFile.isEmpty()) {
pictureValidator.validate(multipartFile, bindingResult);
}
if (bindingResult.hasErrors()) {
return "makeLog";
}
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String username;
if (principal instanceof UserDetails) {
username = ((UserDetails)principal).getUsername();
} else {
username = principal.toString();
}
User currentUser=userService.findByUsername(username);
logForm.setPath(pictureService.getFishPicUploadPath(multipartFile));
logForm.setDate(new Date());
logForm.setUsers(currentUser);
journalService.save(logForm);
return "redirect:/";
}
}
makeLog视图的一部分,显示我的一个下拉菜单:
<form method="POST" class="fish-log" th:object="${logForm}" th:action="@{/makeLog}" enctype="multipart/form-data">
<h2 class="form-signin-heading">Create your Fishing Log</h2>
<div class="form-group">
<select th:field="*{waters}" class="form-control" id="water">
<option value=""selected hidden>Изберете водоем...</option>
<option th:each="water : ${waters}"
th:value="${water.id}"
th:text="${water.name}">
</option>
</select>
<span class="has-error" th:if="${#fields.hasErrors('waters')}" th:errors="*{waters}"></span>
</div>
如果存在验证错误,则需要再次添加模型属性。像这样更新你的@PostMapping
方法;
@PostMapping("/makeLog")
public String makeLog(@ModelAttribute("logForm") FishJournal logForm,
@RequestParam("image") MultipartFile multipartFile, BindingResult bindingResult)throws IOException { {
journalValidator.validate(logForm, bindingResult);
if(!multipartFile.isEmpty()) {
pictureValidator.validate(multipartFile, bindingResult);
}
if (bindingResult.hasErrors()) {
model.addAttribute("waters", waterService.findAll());
model.addAttribute("baits", baitService.findAll());
return "makeLog";
}
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String username;
if (principal instanceof UserDetails) {
username = ((UserDetails)principal).getUsername();
} else {
username = principal.toString();
}
User currentUser=userService.findByUsername(username);
logForm.setPath(pictureService.getFishPicUploadPath(multipartFile));
logForm.setDate(new Date());
logForm.setUsers(currentUser);
journalService.save(logForm);
return "redirect:/";
}
额外的小贴士:
- 您可以使用
@AuthenticationPrincipal
将当前用户注入到方法中,这样您就不必自己使用SecurityContextHolder
了。 BindingResult
变量应该直接在@ModelAttribute
之后,您也应该将@Valid
添加到@ModelAttribute
中。