Comment sérialiser une Date à l'aide AVRO en Java
Je suis en train d'essayer de sérialiser des objets contenant des dates avec Avro, et la désérialisé date ne correspond pas à la valeur attendue (testé avec avro 1.7.2 et 1.7.1). Voici la classe je suis la sérialisation :
import java.text.SimpleDateFormat;
import java.util.Date;
public class Dummy {
private Date date;
private SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss.SSS");
public Dummy() {
}
public void setDate(Date date) {
this.date = date;
}
public Date getDate() {
return date;
}
@Override
public String toString() {
return df.format(date);
}
}
Le code utilisé pour sérialiser /désérialiser :
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Date;
import org.apache.avro.Schema;
import org.apache.avro.io.DatumReader;
import org.apache.avro.io.DatumWriter;
import org.apache.avro.io.Decoder;
import org.apache.avro.io.DecoderFactory;
import org.apache.avro.io.Encoder;
import org.apache.avro.io.EncoderFactory;
import org.apache.avro.reflect.ReflectData;
import org.apache.avro.reflect.ReflectDatumReader;
import org.apache.avro.reflect.ReflectDatumWriter;
public class AvroSerialization {
public static void main(String[] args) {
Dummy expected = new Dummy();
expected.setDate(new Date());
System.out.println("EXPECTED: " + expected);
Schema schema = ReflectData.get().getSchema(Dummy.class);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Encoder encoder = EncoderFactory.get().binaryEncoder(baos, null);
DatumWriter<Dummy> writer = new ReflectDatumWriter<Dummy>(schema);
try {
writer.write(expected, encoder);
encoder.flush();
Decoder decoder = DecoderFactory.get().binaryDecoder(baos.toByteArray(), null);
DatumReader<Dummy> reader = new ReflectDatumReader<Dummy>(schema);
Dummy actual = reader.read(null, decoder);
System.out.println("ACTUAL: " + actual);
} catch (IOException e) {
System.err.println("IOException: " + e.getMessage());
}
}
}
Et la sortie :
EXPECTED: 06/11/2012 05:43:29.188
ACTUAL: 06/11/2012 05:43:29.387
Est-il lié à un bug, ou est-elle liée à la façon dont je suis la sérialisation de l'objet ?
- Je sais que je ne suis pas répondre à votre question, mais je ne voudrais pas utiliser un statique SimpleDateFormat. Ce n'est pas un "thread-safe" de la classe et, par conséquent, vous donnera des résultats peu fiables dans une tige filetée de l'environnement
- Merci pour le commentaire, ce n'est effectivement pas un code de production, mais seulement une classe de test que j'ai développé afin d'exposer mon problème. De toute façon vous avez raison, j'ai donc enlevé le modificateur static 😉
Vous devez vous connecter pour publier un commentaire.
Je pense que AVRO n'est pas sérialiser date à ce point.
Ce que je voudrais faire est de l'envelopper dans une autre classe et les conserver à long (date.gettime ()), tandis que avro gens
ajouter cette fonctionnalité.
Et la raison pour laquelle vous voyez les différentes valeurs de Date, c'est que chaque fois que vous (et avro) créer
un objet Date, il initialise la Date avec l'heure Système actuelle.
Avro 1.8 a maintenant une date de "logicalType", qui annote int. Par exemple:
{"name": "date", "type": "int", "logicalType": "date"}
Citant le spec: "Une date de type logique annote un Avro int, où l'int stocke le nombre de jours depuis l'époque unix (1er janvier 1970 (ISO calendrier)."