Страница перезагрузки загрузки Spring с динамическим URL-адресом в контроллере @PostMapping, когда @Допустимые ограничения ввода не выполняются, для отображения ошибок на веб-странице

#java #spring #controller #annotations #thymeleaf

#java #spring #контроллер #аннотации #thymeleaf

Вопрос:

В настоящее время я работаю над системой управления пользователями для веб-сайта с Java Spring Boot, Thymeleaf и Salespoint Framework для университетского проекта.

На страницах, где пользователи могут редактировать свою информацию, например, адрес электронной почты или пароль, я использую проверку формы, в которой данные хранятся через @Valid аннотацию. Если BindingResult есть ошибки, он должен вернуться на ту же страницу, чтобы показать пользователю входные данные, где что-то было не так. Я использовал это на следующей странице для создания нового пользователя, и он просто отлично работает:

 @PreAuthorize("hasRole('ADMIN')")
@GetMapping("/createmember")
public String createMember(@ModelAttribute("creationForm CreationForm creationForm) {
    return "/createmember";
}

@PreAuthorize("hasRole('ADMIN')")
@PostMapping("/createmember")
public String createMember(@Valid @ModelAttribute("creationForm") CreationForm creationForm, BindingResult bindingResult) {

    if (bindingResult.hasErrors()) {
        return "/createmember";
    }
    //function to create new member
    return "redirect:/memberlist";
}
 

Сообщение об ошибке реализовано на HTML-странице следующим образом:

 <td>
<input id="username" name="username" th:field="*{username}" required type="text" placeholder="Username">
<p th:if="${#fields.hasErrors('username')}" th:errors="*{username}"class="invalidinput">username errors</p>
</td>
 

Проблема начинается, как только я хочу использовать это для страницы с динамическим URL. В следующем коде я хочу изменить пароль пользователя как вошедшего в систему администратора. Чтобы все в системе знали, какой пользователь в данный момент редактируется, я использую динамический URL password/{username} . Чистое изменение пароля также работает нормально, пока я не проверяю, соответствует ли пароль моим требованиям проверки. Он изменяет пароль пользователя, если newPassword и confirmationPassword совпадают, а если нет, пароль не меняется.

 @PreAuthorize("hasRole('ADMIN')")
@GetMapping("password/{username}")
public String password(@PathVariable String username, PasswordForm passwordForm) {
    passwordForm.setUsername(username);
    model.addAttribute("passwordForm", passwordForm);
    return "/password";
}

@PreAuthorize("hasRole('ADMIN')")
@PostMapping("/password")
public String password(@Valid @ModelAttribute PasswordForm passwordForm, BindingResult bindingResult) {
    if (bindingResult.hasErrors()) {
        return "/password";
    }

    if (//checks if both passwords are equal) {
    //function to change password
        return "redirect:/memberlist";
    }
    return "redirect:/";
}
 

HTML равен createMember .

Проблема здесь в том, что как только я даю форме недопустимые входные данные и отправляю форму, thymeleaf выдает ошибку:

 Caused by: java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'passwordForm' available as a request attribute
 

И некоторые другие ошибки, вызванные этим.

Если я изменю код на

 if (bindinResult.hasErrors()) {
   return "/password/"   passwordForm.getUsername();
}
 

Thymeleaf не может найти шаблон «/ пароль / имя пользователя».

Однако, если я изменю код на:

 if (bindinResult.hasErrors()) {
   return "redirect:/password/"   passwordForm.getUsername();
}
 

Он перезагружает страницу без проблем, но все исчезло, и он не показывает никаких ошибок, так что это не вариант.

Надеюсь, это не слишком много, я некоторое время искал решения в Интернете, но их не было.

У кого-нибудь есть идеи, в чем может быть проблема?

Ответ №1:

После нескольких часов отсутствия проблемы я только что узнал, что я только забыл установить @ModelAttribute имя. Исправленный код ниже работает нормально.

 @PreAuthorize("hasRole('ADMIN')")
@GetMapping("password/{username}")
public String password(@PathVariable String username, @ModelAttribure("passwordForm") PasswordForm passwordForm) {
    passwordForm.setUsername(username);
    return "/password";
}

@PreAuthorize("hasRole('ADMIN')")
@PostMapping("/password")
public String password(@Valid @ModelAttribute("passwordForm") PasswordForm passwordForm, BindingResult bindingResult) {
    if (bindingResult.hasErrors()) {
        return "/password";
    }

    if (//checks if both passwords are equal) {
    //function to change password
        return "redirect:/memberlist";
    }
    return "redirect:/";
}