簡體   English   中英

用於加密/解密字段的Java Jackson Custom Polymorphc Deserializer

[英]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的各種錯誤。 我希望在我的解串器中實現的是:

  1. 傑克遜,反序列化這個東西,因為你知道如何使用加密字段的類型信息
  2. 在返回之前,讓我對實例進行解密(不需要正確輸入,我可以通過反射訪問)。

這是我到目前為止:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM