【问题标题】:Decode Document to a Java Class using custom Mongo Codec使用自定义 Mongo 编解码器将文档解码为 Java 类
【发布时间】:2017-12-18 10:17:01
【问题描述】:

我正在尝试使用 MongoDB 编解码器功能以自定义格式将 Java ZonedDateTime 对象读写到 Mongo。

插入文档效果很好,但我很难理解如何让 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;
        }
    }
}

【问题讨论】:

    标签: java mongodb codec zoneddatetime


    【解决方案1】:

    我在这里做了一个测试,并检查了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])(伦敦时区的当前日期/时间)。

    【讨论】:

    • 感谢 Hugo,这正是我想要的。我想我只是希望有一些不那么冗长的东西。
    • @AndyMc 我必须承认我不经常使用 MongoDb,所以这是我能得到的最简洁的。
    猜你喜欢
    • 1970-01-01
    • 2020-06-27
    • 2021-01-11
    • 2020-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-14
    • 2020-05-24
    相关资源
    最近更新 更多