是否可以从 dto 和 User 类创建一个 newUser ?

Posted

技术标签:

【中文标题】是否可以从 dto 和 User 类创建一个 newUser ?【英文标题】:Is it possible to create a newUser from the dto and User class? 【发布时间】:2020-09-08 17:04:28 【问题描述】:

我正在尝试创建一个注册表单,它使用我的 DTO 和我的用户类中的字段。我不完全确定要去做,可以使用一些帮助。

我有一个如下所示的用户类:

@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. 

注册表最初设置为要求输入用户名/密码对,然后要求用户再次输入密码以确认密码。因此关联的 DTO 扩展了 LoginFormDTO 并添加了一个额外的字段用于密码验证。当我只要求输入用户名和密码时,我就能够完成注册并更新数据库中的这些列。但是现在我想在注册期间添加其他用户信息。

我的数据传输对象已更新为如下所示...(我已尝试使用或不使用 @Column 注释。

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

我的 LoginFormDTO 看起来像这样...

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;
    



我的AuthenticationController的注册方法是这样的

    @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:";
    

我不确定如何从 dto 和用户类创建新用户。我可以设置用户名和密码,但似乎无法添加firstNamelastNamephoneNumberemail 等用户信息。数据库添加了idpw_hashusername。添加这些字段以便它们显示在数据库中的最佳方法是什么?先感谢您。我从这个有用的社区学到了很多东西!

【问题讨论】:

您的 DTO 应该在 User 类中包含您以后需要的所有字段。 向我们展示您的班级LoginFormDTO。它没有字段 firstNamelastName 等吗? @mentallurg 我想知道这是否可以解决问题。我会试一试。我没有在 LoginFormDTO 中包含这些字段,但将它们包含在 RegistrationDTO 中是有意义的。我应该只使用这种格式:private String firstName,我需要getter和setter吗?这看起来真的是多余的,因为它们已经在 User 类中了。 RegisterFormDTO 扩展类 LoginFormDTO。这意味着您的对象 registerFormDTO 还具有从类 LoginFormDTO 继承的所有字段。 @mentallurg 我在上面添加了 LoginFormDTO。我尝试添加firstNamelastName 等。登录成功,但不会使用附加信息更新数据库。我仍然有点不确定是否应该扩展我的 LoginFormDTo 或只是添加字段? 【参考方案1】:

如何使用字段扩展RegisterFormDTO 类:firstNamelastNamephoneNumberemail

然后,您的User 类应该有另一个支持更多usernamepassword 的构造函数。在这种情况下,要限制构造函数中的参数数量,您可以使用构建器设计模式。

您可以在这里阅读更多内容:Managing constructors with many parameters in Java


关于命名约定的另一件事,如果您的名字包含超过两个字符的大写快捷方式,您应该继续使用 PascalCase:RegisterDTO -> RegisterDto

见:Java Naming Convention with Acronyms

【讨论】:

正式地说你是对的。在一个由 10 名开发人员组成的团队中,一个项目工作 1-2 年,这样的事情是显而易见的。但她是初学者,据我了解,她可能独自一人这样做。如果您是初学者,很难理解严格遵循某种编码风格的价值:) @mentallurg 这就是为什么我留下一些链接以阅读更多内容。总有改进的地方,但你需要以某种方式得到指导:) @mslowiak 感谢您的提示!我的 RegisterFormDto 由 LoginFormDto 扩展。我应该通过 User 类来扩展它吗? @AbigailHowe 最好在 RegisterFormDto 中明确定义这 4 个字段,而不是从 User 类扩展。您需要将 dtos 类视为不同于实体的东西 我已经定义了这些字段,但无法让这些数据显示在 mysql 数据库中。一定有什么我错过了。 @mslowiak

以上是关于是否可以从 dto 和 User 类创建一个 newUser ?的主要内容,如果未能解决你的问题,请参考以下文章

是否适合将 DTO 设置为 DAO?

是否有任何工具可以从实体生成 DTO?

采用DTO和DAO对JDBC程序进行进一步优化

将 Alamofire 调用包装到 Swift 中的自定义对象中?

从基类 (DTO) 继承多个类是不是违反了任何 SOLID 原则?

Resultful分布式架构