[英]Java Jackson Custom Polymorphc Deserializer to encrypt/decrypt fields
我有某些對象的某些字段,當序列化存儲在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匹配的空接口,它反射地查找字段並在注釋時發揮其魔力。 序列化步驟就像一個魅力,我得到一個輸出字符串,如:{“ TYPE ”:“Type1”,“encryptedField”:“aGAzLwT47gE / QNlUuAhnJg ==”,“unencryptedField”:“plaintext”}
但解密很糟糕。 我無法使其工作:我不確定將多態性和解密結合起來要實現什么。
如果我刪除了@JsonDeserialize注釋,並讓Jackson做了它的事情,它會正確地反序列化多態,但是使用加密字段。 如果我嘗試使用我的自定義反序列化器,我會遇到從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)構造函數或我真的嘗試過不同的選項,但我一直卡住。
正如您所推斷的那樣,您需要@JsonTypeInfo
用於多態的東西。
自定義反序列化器是實現加密邏輯的一種方法。 如果您願意,您可以在構造函數上嘗試使用@JsonCreator
注釋進行反序列化(並在其中包含解密邏輯),並在自定義的getter上通過@JsonProperty
注釋處理加密。
關於“EncryptedDeserializer沒有默認(無arg)構造函數”的具體錯誤 - 為什么不創建一個(即使它是private
)? 傑克遜通過反思將這些東西用於實例化。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.