2017-10-20 9 views
0

ジャーナルデシリアライザを実装して、JSONが変更されたときにJSONを移行する方法を考えています(たとえば、名前が変更されたフィールドのように、今や一貫性のないJSON一貫性のあるものにする)。ジャーナルのカスタムデシリアライゼーション - JsonParserを2回読み取ることができない

これを実行する方法の1つは、JsonDeserializerを作成し、適切な最終クラスとしてJSONを読み取り、MAPとして再度読み取って、変更を選択することです。

JSONを読み込んだり逆シリアル化するたびに、バッキングストリームが閉じられるため、私はそれを行うようには見えません。私は、私は何とかいくつかの中でのデシリアライズを委任することができるようにしたいMyPOJOカスタムデシリアライザを使用していたときに、例えば、カスタム日付デシリアライザで、既にカスタマイズされたものがあるので、新しいObjectMapperを作成避けています

class CustomDeserializer extends StdDeserializer<MyPOJO> implements ResolvableDeserializer{ 

    private final JsonDeserializer<?> deserializer; 
    private final ObjectMapper mapper; 

    public CustomDeserializer(JsonDeserializer<?> deserializer, ObjectMapper mapper) { 
     super(MyPOJO.class); 
     this.deserializer = deserializer; 
     this.mapper = mapper; 
    } 

    @Override 
    public MyPOJO deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { 
     MyPOJO deserialized = (MyPOJO) deserializer.deserialize(jp, ctxt); 
     // Custom migration would go here... 
     return deserialized; 
    } 

    @Override 
    public void resolve(DeserializationContext ctxt) throws JsonMappingException { 
     ((ResolvableDeserializer) deserializer).resolve(ctxt); 
    } 
} 

以前の設定をすべて使用します。

答えて

0

これは私が思い付いたものです:私は基本的に私のPOJOとしてではなく、すべてのフィールドと同じものである「HistoryPOJO」に私のPOJOをデシリアライズしていますシリアライザで

@Autowired 
    public Serializer(List<IDeserializer> deserializers) { 
     SimpleModule module = new SimpleModule("name"); 
     registerDeserializers(module, deserializers); 
     mapper.registerModule(module); 
     mapper.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true); 
     mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); 
     mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd")); 
    } 

    private void registerDeserializers(SimpleModule module, List<IDeserializer> deserializers) { 
     if (CollectionUtils.isNotEmpty(deserializers)) { 
      final Map<Class<?>, IDeserializer> deserializerRegistryMap = toMap(deserializers); 
      module.setDeserializerModifier(new BeanDeserializerModifier() { 
       @Override 
       public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer) { 
        if (deserializerRegistryMap.containsKey(beanDesc.getBeanClass())){ 
         return deserializerRegistryMap.get(beanDesc.getBeanClass()).getDeserializer(mapper); 
        } 
        return super.modifyDeserializer(config, beanDesc, deserializer); 
       } 
      }); 
     } 
    } 


@Component 
public class MigrationDeserializer { 

    @Autowired 
    private MigratorRegistry migratorRegistry; 

    public <T> JsonDeserializer<T> createDeserializer(final ObjectMapper mapper, final Class<T> returnType, final Class<? extends SerializedObjectsHistory<T>> historyType){ 
     return new StdDeserializer<T>(returnType){ 

      @Override 
      public T deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { 
       SerializedObjectsHistory<T> history = mapper.readValue(p, historyType); 
       return migratorRegistry.migrate(history, returnType); 
      } 
     }; 
    } 
} 

、でも名前を変更/削除もの。

次に、私はそれを現在のバージョンに変換します。

関連する問題