我有某些对象的某些字段,当序列化存储在DB中时,需要加密。
在内存中不需要加密。我希望以透明的方式实现对代码库的其余部分,所以我想把enc / dec步骤放在ser / deser级别。
为了通用,我创建了一个界面和一个注释:
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "__TYPE__")
@JsonSubTypes({
@JsonSubTypes.Type(value = Type1.class, name = "Type1"),
@JsonSubTypes.Type(value = Type2.class, name = "Type2"),
@JsonSubTypes.Type(value = Type3.class, name = "Type3")
})
@JsonSerialize(using=EncryptedSerializer.class)
@JsonDeserialize(using=EncryptedDeserializer.class)
public interface EncryptedType {}
和
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface EncryptedField {}
这个想法是这些类将实现空接口以匹配自定义ser / deser,如果它们被注释,它们会反射地查找字段并发挥其魔力。序列化步骤就像一个魅力,我得到一个输出字符串,如: {"的类型":"类型1"" encryptedField":" aGAzLwT47gE / QNlUuAhnJg ==&#34 ;, " unencryptedField":"明文"}
但解密很糟糕。我无法使其发挥作用:我不确定将多态性和解密结合起来要实现什么。
如果我删除了@JsonDeserialize注释,让杰克逊做了它的事情,它会正确地反序列化多态,但加密字段。如果我尝试使用我的自定义反序列化器,我会遇到从NPE到Jackson的各种错误。我希望在我的解串器中实现的是:
这是我到目前为止所做的:
public class EncryptedDeserializer extends StdDeserializer<EncryptedType> {
[..super etc..]
@Override
public EncryptedType deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
return null;
}
@Override
public EncryptedType deserializeWithType(JsonParser p, DeserializationContext ctxt,
TypeDeserializer typeDeserializer) throws IOException {
EncryptedType newInstance = super.deserializeWithType(p, ctxt, typeDeserializer);
Field[] fields = newInstance.getClass().getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(EncryptedField.class)) {
boolean accessibility = field.isAccessible();
field.setAccessible(true);
try {
field.set(newInstance, ApplicationContextRegister.getApplicationContext().getBean(TextEncryptionService.class).decrypt((String) field.get(newInstance)));
} catch (Exception e) {
log.error("Could not decryption field " + field.getName() + " of " + newInstance + ". Skipping decryption");
}
field.setAccessible(accessibility);
}
}
return newInstance;
}
但这失败了,错误或抱怨EncryptedDeserializer没有默认(没有arg)构造函数,或者我真的尝试了不同的选项,但我一直陷入困境。
答案 0 :(得分:0)
正如您所推断的那样,您需要@JsonTypeInfo
多态性的东西。
自定义反序列化器是实现加密逻辑的一种方法。如果您愿意,您可以随时在构造函数上尝试@JsonCreator
注释以进行反序列化(并在其中包含解密逻辑),并在自定义的getter上通过@JsonProperty
注释处理加密。
关于“EncryptedDeserializer没有默认(无arg)构造函数”的特定错误 - 为什么不创建一个(即使它是private
)?杰克逊通过反思将这些东西用于实例化。