2017-08-31 4 views
0

Prenons l'exemple suivant:@JsonDeserializer dans mixin

J'ai une chaîne JSON = {"timestamp":1504111920} qui doit être converti en classe CodeTimestamp. L'horodatage présent dans la chaîne json ci-dessus est à l'époque seconde.

classe CodeTimestamp:

@Getter 
@Setter 
@NoArgsConstructor 
class CodeTimestamp { 
    private Date timestamp; 
} 

En utilisant directement fasterxml jackson cartographe, je ne serai pas en mesure d'obtenir la date exacte car elle suppose l'horodatage d'être en époque milliseconde. Donc, je devrais écrire un désérialiseur personnalisé.

Cependant, je ne peux pas éditer/modifier la classe CodeTimestamp. Est-il possible d'écrire JsonDeserializer dans mixin?

Je suis confronté à des problèmes lors de la désérialisation. Voici le code:

public abstract class StreamRecordMixIn { 

     @JsonDeserialize(using = UnixTimestampDeserializer.class) 
     private Date approximateCreationDateTime; 
} 

    public class UnixTimestampDeserializer extends JsonDeserializer<Date> { 

     @Override 
     public Date deserialize(JsonParser parser, DeserializationContext context) 
       throws IOException, JsonProcessingException { 
      String unixTimestamp = parser.getText().trim(); 
      return new Date(TimeUnit.SECONDS.toMillis(Long.valueOf(unixTimestamp))); 
     } 
    } 

code pour initialiser et utiliser l'objet mappeur:

ObjectMapper objectMapper = new ObjectMapper(); 

objectMapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true); 
     objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 

objectMapper.addMixIn(CodeTimestamp.class, StreamRecordMixIn.class); 

CodeTimestamp codeTimeStamp = objectMapper.readValue(payload, CodeTimestamp.class); 

Erreur:

Causée par: java.lang.IllegalArgumentException: Classe com.test.TestConverter $ UnixTimestampDeserializer n'a pas de constructeur par défaut (sans argument) at com.fasterxml.jackson.databind.util.ClassUtil.createInstance (ClassUtil.java:378) at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.deserializerI nstance (DefaultDeserializationContext.java:218) à com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.findDeserializerFromAnnotation (BasicDeserializerFactory.java:1735) à com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.constructSettableProperty (BeanDeserializerFactory.java: 730) à com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.addBeanProps (BeanDeserializerFactory.java:507) à com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer (BeanDeserializerFactory.java:229) à com. fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer (BeanDeserializerFactory.java:142) à com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2 (DeserializerCache.java:403) à com .fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer (DeserializerCache.java:352) à com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2 (DeserializerCache.java:264) ... 23 plus

+0

double possible de [Comment puis-je deserialize horodatages qui sont en quelques secondes avec Jackson?] (Https://stackoverflow.com/questions/20635698/how-do-i-deserialize-timestamps-that-are- in-seconds-with-jackson) – nullpointer

+0

* Y at-il un moyen d'écrire JsonDeserializer dans mixin? * Bien sûr, quel est le problème? – shmosel

+0

@nullpointer La solution fournie utilise des annotations sur la classe réelle. Je ne suis pas sûr que la même chose puisse être faite dans mixin. J'ai mis à jour la question pour plus de clarté. –

Répondre

0

L'erreur ici est un désérialiseur personnalisé non déclaré comme statique. Donc, si je l'ai utilisé comme mentionné ci-dessous, cela fonctionne.

public static class UnixTimestampDeserializer extends JsonDeserializer<Date> { 

    @Override 
    public Date deserialize(JsonParser parser, DeserializationContext context) 
      throws IOException, JsonProcessingException { 
     String unixTimestamp = parser.getText().trim(); 
     return new Date(TimeUnit.SECONDS.toMillis(Long.valueOf(unixTimestamp))); 
    } 
}