Search code examples
javaspring-bootgradlethymeleaf

Is it possible to create a newUser from the dto and User class?


I'm trying to create a registration form that uses fields from my DTO and my User class. I'm not exactly sure to go about it and could use some help.

I have a User class that looks like this:

@Entity
public class User extends AbstractEntity {

    @NotNull
    private String username;

    @NotNull
    private String pwHash;

    @Column(name = "first_name")
    private String firstName;
    @Column(name = "last_name")
    private String lastName;
    @Column(name = "email")
    private String email;
    @Column(name = "phone_number")
    private String phoneNumber;



    public User() {}

    public User(String username, String password) {
        this.username = username;
        this.pwHash = encoder.encode(password);
    }

    public String getUsername() {
        return username;
    }

    private static final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

    public boolean isMatchingPassword(String password) {
        return encoder.matches(password, pwHash);
    }

// ---> Removed Getters and setters removed for brevity. 

The registration form originally was set up to ask for a username/password pair, and then ask the user to confirm the password by typing it in again. So the associated DTO extended the LoginFormDTO and added an additional field for password verification. When I only asked for a username and password I was able to complete the registration and update those columns in my database. However now I'd like to add additional user information during registration.

My data transfer object has been updated to look like this... (I've tried this with and without the @Column annotations.

public class RegisterFormDTO extends LoginFormDTO{

    private String verifyPassword;

    @Column(name = "first_name")
    private String firstName;
    @Column(name = "last_name")
    private String lastName;
    @Column(name = "email")
    private String email;
    @Column(name = "phone_number")
    private String phoneNumber;



    public String getVerifyPassword() {
        return verifyPassword;
    }

    public void setVerifyPassword(String verifyPassword) {
        this.verifyPassword = verifyPassword;
    }

    public String getFirstName() {
        return firstName;
    }
// additional pojo getters and setters

My LoginFormDTO looks like this...

public class LoginFormDTO {

    @NotNull
    @NotBlank
    @Size(min = 3, max = 20, message = "Invalid username. Must be between 3 and 30 characters.")
    private String username;

    @NotNull
    @NotBlank
    @Size(min = 5, max = 20, message = "Invalid password. Must be between 5 and 30 characters.")
    private String password;



    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }


}

My AuthenticationController's registration method looks like this

    @PostMapping("/register")
    public String processRegistrationForm(@ModelAttribute @Valid RegisterFormDTO registerFormDTO,
                                          Errors errors, HttpServletRequest request,
                                          Model model) {

        if (errors.hasErrors()) {
            model.addAttribute("title", "Register");
            return "register";
        }

        User existingUser = userRepository.findByUsername(registerFormDTO.getUsername());

        if (existingUser != null) {
            errors.rejectValue("username", "username.alreadyexists", "A user with that username already exists");
            model.addAttribute("title", "Register");
            return "register";
        }

        String password = registerFormDTO.getPassword();
        String verifyPassword = registerFormDTO.getVerifyPassword();
        if (!password.equals(verifyPassword)) {
            errors.rejectValue("password", "passwords.mismatch", "Passwords do not match");
            model.addAttribute("title", "Register");
            return "register";
        }

        User newUser = new User(registerFormDTO.getUsername(), registerFormDTO.getPassword(), registerFormDTO.getFirstName(), registerFormDTO.getLastName(), registerFormDTO.getPhoneNumber(), registerFormDTO.getEmail());
        userRepository.save(newUser);
        setUserInSession(request.getSession(), newUser);

        return "redirect:";
    }

I'm not sure how to create a new user from the dto and the user class. I'm able to set the username and password but can't seem to add user info like firstName, lastName, phoneNumber or email. The database adds the id, pw_hash and username. What is the best way to go adding these fields so that they show up in the database? Thank you in advance. I'm learning so much from this helpful community!


Solution

  • How about extending RegisterFormDTO class with fields: firstName, lastName, phoneNumber, email?

    Then, your User class should have another constructor that supports more than username and password. In this case to limit the number of arguments in the constructor you can use a builder design pattern.

    You can read more here: Managing constructors with many parameters in Java


    And one more thing about naming convention, if your name contains uppercase shortcut that is longer than two characters you should proceed with PascalCase: RegisterDTO -> RegisterDto.

    See: Java Naming Convention with Acronyms