Spring Boot 错误:Bean名称'firstName'的BindingResult和普通目标对象都不能用作请求属性

uyhoqukh  于 2023-03-12  发布在  Spring
关注(0)|答案(1)|浏览(154)

我收到此错误:BindingResult和bean名称“firstName”的普通目标对象都不能用作请求属性。我一直在尝试使用springboot验证库为表单的元素添加验证。
网址:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://thymeleaf.org">
<head>
    <link rel="stylesheet" type="text/css" media="all"
          href="/../static/css/styles.css" th:href="@{/css/styles.css}" />
    <meta http-equiv="Content-Type" context="text/html; charset=UTF-8">
    <title>Register</title>
</head>
<body>
    <div class="registerUser">
        <h1> Register </h1>

        <form th:action="@{register}" method="post">
            <label for="firstName"> First Name: </label>
            <input type="text" class="form-control" id="firstName" placeholder="First name"
                   th:name="firstName" th:value="*{firstName}" data-cy="firstName" required autofocus>
            <p th:if="${#fields.hasErrors('firstName')}">Invalid first name</p>

            <br/>
            <label for="lastName"> Last Name: </label>
            <input type="text" class="form-control" id="lastName" placeholder="Last name"
                   th:name="lastName" th:value="*{lastName}" data-cy="lastName" required
                   autofocus>
            <br/>
            <label for="dateOfBirth"> Date of birth: </label>
            <input type="date" class="form-control" id="dateOfBirth" placeholder="Name"
                   th:name="dateOfBirth" th:value="*{dateOfBirth}" data-cy="dateOfBirth" required autofocus>
            <br/>
            <label for="email"> Email: </label>
            <input type="email" class="form-control" id="email" placeholder="Email"
                   th:name="email" th:value="*{email}" data-cy="email" required autofocus>
            <br/>
            <label for="password"> Password: </label>
            <input type="password" class="form-control" id="password" placeholder="Password"
                   th:name="password" th:value="*{password}" data-cy="password" required autofocus>
            <button type="submit">Register</button>
        </form>
    </div>
</body>
</html>

用户实体:只是我加的验证部分

@NotEmpty(message = "User's name cannot be empty.")
    @Size(min = 5, max = 250)
    @Column(nullable = false)
    private String firstName;

在寄存器控制器中

@PostMapping("/register")
    public String register(@Valid HttpServletRequest request,
                           @RequestParam(name = "email") String email,
                           @RequestParam(name = "firstName") String firstName,
                           @RequestParam(name = "lastName") String lastName,
                           @RequestParam(name= "password") String password,
                           @RequestParam(name = "dateOfBirth")@DateTimeFormat(pattern = "yyyy-MM-dd") Date dateOfBirth,
                           BindingResult result)
            {

                if (result.hasErrors()) {
                    return "redirect:/addUser";
                }

        // Note that there are no sanity checks on users (i.e. can have duplicate emails)
                User user = new User(firstName, lastName, dateOfBirth, email,  password);
                user.grantAuthority("ROLE_USER");

                userService.updateOrAddUser(user);

                UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(user.getEmail(), user.getPassword(), user.getAuthorities());
                Authentication authentication = authenticationManager.authenticate(token);
                if(authentication.isAuthenticated()){
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                    request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());
                }

                return "redirect:/user";
            }

整个例外:https://pastebin.com/kYr4xd7y

yc0p9oo0

yc0p9oo01#

我建议使用专用的窗体支持对象,例如CreateUserFormData
然后更新您的控制器以使用:

@GetMapping("/register")
    public String showCreateUserForm(Model model) {
        model.addAttribute("formData", new CreateUserFormData());
        return "users/create";
    }

    @PostMapping("/register")
    public String doCreateUser(@Valid @ModelAttribute("formData") CreateUserFormData formData,
                               BindingResult bindingResult,
                               Model model) {
        if (bindingResult.hasErrors()) {
            return "users/create"; // Use the same template name as you return in your `GetMapping` controller method
        }

        // I like to add a method on the form data object to turn itself into a parameters object to give to the service
        service.createUser(formData.toParameters());

        // Redirect if all went ok
        return "redirect:/users";
    }

同时更新Thymeleaf模板以使用formdata对象:

<form th:action="@{register}" th:object="${formData}" method="post">

参见Form handling with Thymeleaf

相关问题