我正在编写一个JavaFX程序,它应该有用户管理和数据库后端。我的数据模型类都使用JavaFX样式的属性(为了更容易的UI集成,请参阅例如this)。
但是现在我遇到了一个技术问题,我的User
课程需要byte[]
个字段 - 即password hash和salt这些字段。
由于MessageDigest
和类似的Java服务期望byte[]
,使用ObjectProperty<Byte[]>
的明显解决方案变得很麻烦,因为每次使用字段时我都必须创建一个新的{{1}并复制值
例如:
byte[]
所以我的问题是 - 是否有一个简单的解决方案,允许我拥有JavaFX风格的属性,我可以使用原始数组获取和设置?
实现像SimpleObjectProperty<Byte[]> toHash = new SimpleObjectProperty<>();
MessageDigest md;
// initialize message digest and Byte[] property here...
// Does not compile - can't convert Byte[] to byte[]
// md.update(toHash.get());
// What does work:
byte[] bytes = new byte[toHash.get().length];
for (int i=0; i<bytes.length; i++)
bytes[i] = toHash.get()[i];
md.update(bytes);
这样的选择是一个合理的选择,还是一个可行的选择?这样的解决方案是否存在?
编辑:我显然忽略了使用PrimitiveByteArrayProperty
的简单解决方案,因为Java认为Java不允许使用原始数组的泛型。
答案 0 :(得分:0)
正确的方法是:
/**
* The password hash.
*/
private final ObjectProperty<byte[]> toHash = new SimpleObjectProperty<>(this, "toHash");
/**
* Setter for toHash property value.
* @param value of the password hash.
*/
public void setToHash(byte[] value){
toHash.set(value);
}
/**
* Getter for toHash property value.
* @return value of the password hash.
*/
public byte[] getToHash(){
return toHash.get();
}
/**
* Accessor to the javaFX property toHash.
* @return toHash javaFX property.
*/
public ObjectPropery<byte[]> toHashProperty(){
return toHash;
}
javaFX约定不返回属性专门化(即:将不返回SimpleObjectProperty),应返回ObjectProperty,StringProperty,BooleanProperty ... 另一方面,toHash听起来像是一个函数名称,它计算哈希值,而不是属性本身。更好的名称可能是passwordHash。或者,如果您在另一个属性中保留密码纯文本(出于安全原因,显然不应该这样做),则正确的javaFX方法应该是:
//The password hash property.
private final ReadOnlyObjectWrapper<byte[]> passwordHash =
new ReadOnlyObjectWrapper<>(this, "passwordHash");
//The password plain text property.
private final StringProperty passwordPlain =
new SimpleStringProperty(this, "passwordPlain");
public byte[] getPasswordHash(){
return passwordHash.get();
}
public ReadOnlyObjectProperty<byte[]> passwordHashProperty(){
return passwordHash.getReadOnlyProperty();
}
public MyClass(){
//Bind your read only property to automatically reflect the plain password changes.
passwordHash.bind(Bindings.createObjectBinding(this::computeHash, passwordPlain));
}
//Invoked from lambda method reference in object binding.
private byte[] computeHash(){
//Here do your stuff to parse the password plain to byte[]
return byteArray;
}