簡體   English   中英

Java處理兩個自定義反序列化器

[英]Java dealing with two custom deserializers

所以這是我遇到的非常奇怪的情況,不知道如何處理。

我有一項服務,其中包含從發送給它的請求中反序列化對象的邏輯。 現在,正在討論的對象正在更改,並且實現了一種新的反序列化方法來處理該問題(不要問為什么,我所知道的就是我們只需要更改反序列化方法即可)。

問題在於此更改需要向后兼容,因此我們應該能夠處理兩種類型的對象。 為此,我們需要能夠根據對象的類型確定要使用的正確的反序列化器,但是如果將對象序列化為字節緩沖區,我們該怎么做呢? 我沒有主意...進行此更改是否有其他/更好的方法?

該服務使用Java。

編輯1:清除我的意圖
舊對象使用了自定義序列化程序,而新對象使用了ObjectMapper JSON序列化程序。 因此,我的目標是能夠檢測到我是在處理舊對象還是新對象,以便可以進行反序列化。
我可以嘗試使用新的反序列化器並捕獲它引發的JsonParseException,並在catch塊中使用舊的序列化器,但這不是我想要處理JsonParseException的方式。

可序列化的類應具有一個serialVersionUID,它是靜態的,最終的且類型為long。 這是為了確保已序列化的對象的類與要反序列化的對象的類相同。

為了實現向后兼容,請按照下列步驟操作:

  1. 確保只要更改類結構,就可以更改此字段的值。
  2. 使用新的自定義序列化器反序列化對象。
  3. 如果對象是上一類的,則將收到InvalidClassException 捕獲此異常,並嘗試使用catch塊中的舊式解串器對該對象進行反序列化。

這樣可以確保您的自定義解串器具有向后兼容性。

首先,您需要確定新對象與舊對象之間的差異 您將使用它來切換到舊的反序列化器。
您還需要為這兩個類(舊的和新的)使用特定的ObjectMapper

創建一個Module並注冊

final SimpleModule module = new SimpleModule();
module.addDeserializer(Object.class, new NewDeserializer(new OldDeserializer()));

final ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(module);

准備新的StdDeserializer ,它將接受舊的作為構造函數參數。

public class NewDeserializer extends StdDeserializer<Object> {
    private final StdDeserializer<Object> oldDeserializer;

    NewDeserializer(final StdDeserializer<Object> oldDeserializer) {
        super(NewObject.class);
        this.oldDeserializer = oldDeserializer;
    }

    @Override
    public Object deserialize(
            final JsonParser parser,
            final DeserializationContext context) throws IOException {
       final ObjectCodec codec = parser.getCodec();

       // Read the JSON document to a tree
       final TreeNode treeNode = codec.readTree(parser);

       // Identify if it is the new format, or the old one
       final TreeNode newField = treeNode.get("newField");

       if (newField == null) {
          // Delegate to the old de-serializer
          final JsonFactory factory = new JsonFactory(parser.getCodec());
          final JsonParser oldParser = factory.createParser(treeNode.toString());
          return oldDeserializer.deserialize(oldParser, context);
       }

       return codec.readValue(treeNode.traverse(), NewObject.class);
    }
}

舊的StdDeserializer

public class OldDeserializer extends StdDeserializer<Object> {
    OldDeserializer() {
        super(OldObject.class);
    }

    @Override
    public Object deserialize(
            final JsonParser parser,
            final DeserializationContext context) throws IOException {
        return parser.getCodec().readValue(parser, OldObject.class);
    }
}

現在,只需致電

objectMapper.readValue(v, Object.class);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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