2017-07-13 6 views
1

Ich versuche die MongoDB-Codec-Funktionalität zu verwenden, um ein Java ZonedDateTime-Objekt in einem benutzerdefinierten Format zu lesen und in Mongo zu schreiben.Dokument in eine Java-Klasse mit benutzerdefiniertem Mongo-Codec decodieren

Das Einfügen von Dokumenten funktioniert gut, aber ich habe Mühe zu verstehen, wie Mongo eine ZonedDateTime zurückgeben kann.

Ich habe den folgenden Testfall um zu versuchen, geschrieben und zeigen:

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

Antwort

0

ich einen Test hier gemacht habe, und überprüft, dass document.get("zonedDateTime") gibt eine org.bson.Document Instanz. Also habe ich nur dieses Objekt auf den Codec übergeben:

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

Die ZonedDateTime Variable (zdt) korrekt erstellt werden (in meinem Test habe ich 2017-07-13T18:07:13.603+01:00[Europe/London] bekam) (das aktuelle Datum/Zeit in London Zeitzone).

+0

Dank Hugo, genau das, was ich gesucht habe. Ich glaube, ich habe nur gehofft, dass es etwas weniger Ausführliches geben könnte. –

+0

@AndyMc Ich muss zugeben, dass ich MongoDb nicht oft benutze, so dass es am wenigsten wortreich ist. –

Verwandte Themen