Spring 引导数据 Rest JPA - 实体自定义创建(用户)

Spring Boot Data Rest JPA - Entity custom create (User)

我正在努力学习Spring。我使用以下工具创建了一个带有 Spring Boot 的项目:

我正在尝试创建一个 User 实体。我希望用户有一个加密密码(+ salt)。

当我执行 POST/api/users 时,我成功创建了一个新用户。

{
"firstname":"John",
"lastname":"Doe",
"email":"johndoe@example.com",
"password":"12345678"
}

但是我有两个问题:

+----+---------------------+-----------+----------+----------+------+
| id |        email        | firstname | lastname | password | salt |
+----+---------------------+-----------+----------+----------+------+
|  1 | johndoe@example.com | John      | Doe      | 12345678 | NULL |
+----+---------------------+-----------+----------+----------+------+

我认为问题是使用了默认构造函数,而不是我创建的另一个构造函数。我是 Spring 和 JPA 的新手,所以我一定遗漏了一些东西。这是我的代码。

User.java

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

    @Id
    @GeneratedValue
    private Long id;

    @Column(nullable = false)
    public String firstname;

    @Column(nullable = false)
    public String lastname;

    @Column(nullable = false, unique = true)
    public String email;

    @JsonIgnore
    @Column(nullable = false)
    public String password;

    @JsonIgnore
    @Column
    private String salt;

    public User() {}

    public User(String email, String firstname, String lastname, String password) {
        this.email = email;
        this.firstname = firstname;
        this.lastname = lastname;
        this.salt = UUID.randomUUID().toString();
        this.password = new BCryptPasswordEncoder().encode(password + this.salt);
    }


    @JsonIgnore
    public String getSalt() {
        return salt;
    }

    @JsonProperty
    public void setSalt(String salt) {
        this.salt = salt;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getFirstname() {
        return firstname;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getLastname() {
        return lastname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

    @JsonIgnore
    public String getPassword() {
        return password;
    }

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

}

UserRepository.java

public interface UserRepository extends JpaRepository<User, Long> {

    public User findByEmail(String email);

    public User findByEmailAndPassword(String email, String password);
}

Application.java

@SpringBootApplication
public class Application {


    public static void main(String[] args) {
        SpringApplication.run(Application .class, args);
    }

}

另外,如果有人发现我做错了,我想指出我where/how我应该把用户登录码(解密)。

谢谢。

如果你想Spring使用你的构造函数,你需要

  • 删除无参数构造函数
  • @JsonProperty 像这样
  • 注释另一个构造函数中的每个参数
public User(@JsonProperty("email") String email, 
            @JsonProperty("firstname") String firstname, 
            @JsonProperty("lastname") String lastname, 
            @JsonProperty("password") String password) {
    this.email = email;
    this.firstname = firstname;
    this.lastname = lastname;
    this.password = new BCryptPasswordEncoder().encode(password);
}

您不需要向 BCryptPasswordEncoder 提供加盐值,因为它本身已经加盐了密码。

所以,这就是我解决问题的方法:我创建了一个控制器作为我的自定义端点,然后我创建了一个服务,在其中放置了我想要创建用户的逻辑。这是代码:

UserController.java

@Controller
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping("/api/register")
    @ResponseBody
    public Long register(@RequestBody User user) {
        return userService.registerUser(user);
    }

    ...

}

用户服务.java

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public Long registerUser(User user) {
        user.setPassword(new BCryptPasswordEncoder().encode(password));
        userRepository.save(user);
        return user.getId();
    }

        ...

}

所以通过 POST

{
"firstname":"John",
"lastname":"Doe",
"email":"johndoe@example.com",
"password":"12345678"
}

/api/register 中,我现在可以使用散列密码创建用户。