spring boot 和 thymeleaf 验证失败后如何保留下拉输入值

How to keep dropdown input values after validation fails with spring boot and thymeleaf

我正在使用 Spring boot 和 thymeleaf,project.I 有一个由文本字段、下拉菜单和文件输入字段组成的表单。下拉列表由我在视图的 getControler 中发送的模型填充。当我将 returns 用户的字段添加到同一页面并显示错误消息时,下拉列表中的所有值都消失了,文件也不存在。如何在验证失败后保持下拉列表的填充。

控制器:

@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