评估SpringEL表达式的异常:“#fields.hasErrors('something')”

时间:2018-10-15 11:41:38

标签: java spring-mvc spring-boot thymeleaf

我尝试为我的应用程序创建一个注册页面,当我按下“提交”按钮时,出现此错误: Exception evaluating SpringEL expression: "#fields.hasErrors('firstName')"

据我了解,Thymleaf使用POJO的getter进行验证,这意味着找不到firstName属性。对于注册,我将DTO用于用户实体,将DTO仅用于注册。如果我使用用户实体,则不会出现此错误。我在做什么错了?

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Registration Form</title>
    <link rel="stylesheet" type="text/css" th:href="@{/css/registration.css}"/>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>

<div class="container">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <form autocomplete="on" action="register.html" th:action="@{/user/register}"
                  th:object="${user}" method="post" class="form-horizontal"
                  role="form">
                <h2>Registration Form</h2>
                <div class="form-group">
                    <div class="col-sm-9">
                        <label th:if="${#fields.hasErrors('firstName')}" th:errors="*{firstName}"
                               class="validation-message"></label>
                        <input type="text" th:field="*{firstName}" placeholder="Name"
                               class="form-control"/>
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-sm-9">
                        <label th:if="${#fields.hasErrors('lastName')}" th:errors="*{lastName}"
                               class="validation-message"></label>
                        <input type="text" th:field="*{lastName}"
                               placeholder="Last Name" class="form-control"/>
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-sm-9">
                        <label th:if="${#fields.hasErrors('username')}" th:errors="*{username}"
                               class="validation-message"></label>
                        <input type="text" th:field="*{username}"
                               placeholder="Username" class="form-control"/>
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-sm-9">
                        <input type="text" th:field="*{emailAddress}" placeholder="Email"
                               class="form-control"/> <label
                            th:if="${#fields.hasErrors('emailAddress')}" th:errors="*{emailAddress}"
                            class="validation-message"></label>
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-sm-9">
                        <label th:if="${#fields.hasErrors('phoneNumber')}" th:errors="*{phoneNumber}"
                               class="validation-message"></label>
                        <input type="text" th:field="*{phoneNumber}"
                               placeholder="Phone Number" class="form-control"/>
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-sm-9">
                        <input type="password" th:field="*{password}"
                               placeholder="Password" class="form-control"/> <label
                            th:if="${#fields.hasErrors('password')}" th:errors="*{password}"
                            class="validation-message"></label>
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-sm-9">
                        <input type="password" th:field="*{confirmPassword}"
                               placeholder="Confirm Password" class="form-control"/> <label
                            th:if="${#fields.hasErrors('confirmPassword')}" th:errors="*{confirmPassword}"
                            class="validation-message"></label>
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-sm-9">
                        <button type="submit" class="btn btn-primary btn-block">Register User</button>
                    </div>
                </div>

                <h2><span class="text-success" th:utext="${successMessage}"></span></h2>

            </form>
        </div>
    </div>
</div>

</body>
</html>

RegisterUserDto

@PasswordMatches
public class RegisterUserDto {

    private Long id;

    @NotNull(message = "This field can't be null")
    @NotEmpty(message = "This field can't be empty")
    private String firstName;

    @NotNull(message = "This field can't be null")
    @NotEmpty(message = "This field can't be empty")
    private String lastName;

    @NotNull(message = "This field can't be null")
    @NotEmpty(message = "This field can't be empty")
    private String username;

    @NotNull(message = "This field can't be null")
    @NotEmpty(message = "This field can't be empty")
    @ValidEmail
    private String emailAddress;

    @NotNull(message = "This field can't be null")
    @NotEmpty(message = "This field can't be empty")
    @ValidPhoneNumber
    private String phoneNumber;

    @ValidPassword
    private String password;

    private String confirmPassword;

    //getters and setters

控制器

 @GetMapping("/register")
    public ModelAndView registration(){

        ModelAndView modelAndView = new ModelAndView();
        RegisterUserDto user = new RegisterUserDto();
        modelAndView.addObject("user", user);
        modelAndView.setViewName("register");

        return modelAndView;
    }

    @PostMapping("/register")
    public ModelAndView createNewUser(@Valid RegisterUserDto user,
                                      BindingResult bindingResult) {

        ModelAndView modelAndView = new ModelAndView();

        User userExists = userService.findUserByEmail(user.getEmailAddress());

        if (userExists != null) {
            bindingResult
                    .rejectValue("emailAddress", "error.user",
                            "There is already a user registered with the email provided");
        }

        if (bindingResult.hasErrors()) {
            modelAndView.setViewName("register");

        } else {
            userService.createUser(user);

            modelAndView.addObject("successMessage", "User has been registered successfully");
            modelAndView.setViewName("register");

        }
        return modelAndView;
    }

用户实体

@Entity
@Table(name = "user")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "user_id")
    private Long id;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    @Column(name = "username",
            unique = true)
    private String username;

    @Column(name = "email_address",
            unique = true)
    private String emailAddress;

    @Column(name = "phone_number")
    private String phoneNumber;

    @Column(name = "password")
    private String password;

    @Column(name = "notification_type",
    insertable = false)
    private String notificationType = "email";

    @Column(name = "date_created")
    private Date dateCreated;

    @Column(name = "is_active",
    insertable = false)
    private Boolean active = false;

    @OneToMany(
            mappedBy = "user",
            cascade = CascadeType.ALL,
            orphanRemoval = true
    )
    private List<UserGroup> groups;

    @OneToMany(
            mappedBy = "user",
            cascade = CascadeType.ALL,
            orphanRemoval = true
    )
    private List<Message> messages = new ArrayList<>();

    @OneToOne(fetch = FetchType.LAZY,
            cascade = {CascadeType.DETACH, CascadeType.MERGE,
                    CascadeType.REFRESH, CascadeType.PERSIST},
            mappedBy = "userId",
            orphanRemoval = true)
    private VerificationToken verificationToken;

    @OneToMany(mappedBy = "createdBy",
            cascade = {CascadeType.DETACH, CascadeType.MERGE,
                    CascadeType.REFRESH, CascadeType.PERSIST},
            orphanRemoval = true)
    private List<Group> createdGroups = new ArrayList<>();

    //getters and setters

0 个答案:

没有答案