2017-07-13 97 views
1

我试图使用MongoDB Codec功能以自定义格式读取和写入Mongo的Java ZonedDateTime对象。使用自定义Mongo Codec将文档解码为Java类

插入文档工作得很好,但我很努力去理解如何让Mongo返回ZonedDateTime

我已经写了下面的测试案例,以尝试并证明:

public class ZonedDateTimeTest { 

    @Test 
    public void serializeAndDeserializeZonedDateTime() throws Exception { 
     CodecRegistry codecRegistry = fromRegistries(
       CodecRegistries.fromCodecs(new ZonedDateTimeCodec()), 
       MongoClient.getDefaultCodecRegistry() 
     ); 
     MongoClient mongoClient = new MongoClient(
       "localhost:27017", 
       MongoClientOptions.builder() 
         .codecRegistry(codecRegistry) 
         .build() 
     ); 
     ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("Europe/London")); 

     MongoCollection<Document> collection = mongoClient 
       .getDatabase("test") 
       .getCollection("test"); 

     // Insert a document 
     collection.insertOne(new Document("_id", 1).append("zonedDateTime", zonedDateTime)); 

     // Find the document just inserted 
     Document document = collection 
       .find(new Document("_id", 1)) 
       .first(); 

     // How to "get" a ZonedDateTime? 
     document.get("zonedDateTime"); 
    } 

    private static class ZonedDateTimeCodec implements Codec<ZonedDateTime> { 
     @Override 
     public Class<ZonedDateTime> getEncoderClass() { 
      return ZonedDateTime.class; 
     } 

     @Override 
     public void encode(BsonWriter writer, ZonedDateTime value, 
          EncoderContext encoderContext) { 
      writer.writeStartDocument(); 
      writer.writeString("dateTime", DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(value)); 
      writer.writeString("offset", value.getOffset().toString()); 
      writer.writeString("zone", value.getZone().toString()); 
      writer.writeEndDocument(); 
     } 

     @Override 
     public ZonedDateTime decode(BsonReader reader, DecoderContext decoderContext) { 
      reader.readStartDocument(); 
      ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(
        LocalDateTime.from(DateTimeFormatter.ISO_LOCAL_DATE_TIME.parse(reader.readString("dateTime"))), 
        ZoneOffset.of(reader.readString("offset")), 
        ZoneId.of(reader.readString("zone")) 
      ); 
      reader.readEndDocument(); 
      return zonedDateTime; 
     } 
    } 
} 

回答

0

我在这里做了一个试验,并检查document.get("zonedDateTime")返回org.bson.Document实例。所以,我刚刚过了这个对象的编解码器:

import org.bson.BsonReader; 
import org.bson.Document; 
import org.bson.json.JsonReader; 
import org.bson.codecs.DecoderContext; 

Object object = document.get("zonedDateTime"); 

ZonedDateTimeCodec codec = (ZonedDateTimeCodec) codecRegistry.get(ZonedDateTime.class); 
BsonReader reader = new JsonReader(((Document) object).toJson()); 
ZonedDateTime zdt = codec.decode(reader, DecoderContext.builder().build()); 
System.out.println(zdt); 

ZonedDateTime变量(zdt)将正确创建(在我的测试中,我有2017-07-13T18:07:13.603+01:00[Europe/London])(当前日期/伦敦时区时间)。

+0

感谢雨果,这正是我一直在寻找的。我想我只是希望可能会有一些不太详细的内容。 –

+0

@AndyMc我必须承认,我不经常使用MongoDb,所以这是我可以得到的最不详细的。 –