我有以下实体:
@Entity
public class User {
@Id
private Integer id;
private String username;
private String password;
}
要设置密码,必须提供明文密码,但存储的实际密码是纯文本密码的哈希值。问题是实际的哈希计算是依赖于业务的。更具体地说,我有以下接口和会话Bean:
public interface PasswordHash {
String hash(String password);
}
@Stateless
public class UserManager {
@Inject
private PasswordHash phash;
public void changeUserPassword(User user, String newPassword) {
String passwordHash = phash.hash(newPassword);
/*Set password of 'user'*/
}
}
有没有办法为User实体的'password'字段设计一个setter,以便UserManager可以更改其值,但没有其他人可以做到这一点?如果不可能,有没有其他方法可以安全地设置密码,而不会将PasswordHash接口暴露给客户端?请注意,CDI不可用于Entity类,因此我无法直接将PasswordHash实例注入其中。
答案 0 :(得分:1)
解决这个问题的一种方法是不直接从服务层公开User实体,只在内部使用它来实现持久性。你通常最终做的是基本上复制一些实体,并来回复制东西。这些"复制"类有时称为数据传输对象。有一些像Dozer这样的工具可以让这更容易,虽然可以说并不漂亮。
第二种方法是对抗Enterprise Java,并避免这些Anemic Objects。迟早,您可能必须进行编程查找,因为正如您所说,实体不支持CDI。这也不是很好,但至少你会得到一些更面向对象的东西。