2012-11-06 11 views
8

Aslında Avro ile tarihleri ​​içeren nesneleri serileştirmeye çalışıyorum ve seri hale getirilmiş tarih beklenen değere uymuyor (avro 1.7.2 ve 1.7.1 ile test edildi).Java'da AVRO Kullanarak Bir Tarih Nasıl Serileştirilir

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); 
    } 
} 

/deserialize seri hale getirmek için kullanılan kod:

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()); 
     } 
    } 
} 

Ve çıktı: İşte seri ediyorum sınıfı var

EXPECTED: 06/11/2012 05:43:29.188 
ACTUAL: 06/11/2012 05:43:29.387 

bilinen bir hatadan bunu ilgili mi, yoksa nesneyi serileştirme şekline mi bağlı?

+1

Sorunuzu yanıtlamadığımı biliyorum, ancak * statik bir SimpleDateFormat kullanmam. Bu iş parçacığı için güvenli bir sınıf değildir ve sonuç olarak dişli bir ortamda güvenilmez sonuçlar verir –

+0

Yorumunuz için teşekkürler, bu aslında bir üretim kodu değil, yalnızca sorunumu açığa çıkarmak için geliştirdiğim bir test sınıftır. Her neyse haklısın, bu yüzden statik değiştiriciyi kaldırdım;) –

cevap

6

AVRO'nun bu noktada tarihi seri hale getirmediğini düşünüyorum. Yapacağım şey, başka bir sınıfa sarmak ve uzun bir tarihte saklamak (date.gettime()) iken, avro üyeleri this feature'u eklemektir. Ve farklı Tarih değerlerini görmenizin nedeni, (ve avro) bir Date nesnesini her oluşturduğunuzda, Tarih'i geçerli Sistem saatiyle başlatır.

+0

Teşekkür ederiz amas, Tarih'in aslında cevabınızda belirtildiği gibi desteklenmediği ve Tarih'in geçerli Sistem zamanı ile başlatıldığı anlaşılıyor. –

7

Avro 1.8, int ek açıklama yapan bir "logicalType" tarihine sahip. Örneğin:

{ "adı,": "tarihi", "tipi": "int", "logicalType": "tarihi"} spec teklif

: "Bir tarih lojik türünden bir Avro int not ekler int, 1 Ocak 1970 (ISO takvimi) unix döneminden gün sayısını saklar.

İlgili konular