MongoDB中Document里有LocalDateTime类toJson抛异常解决办法

12 篇文章 1 订阅

MongoDB中Document里有LocalDateTime类toJson抛异常解决办法

当MongoDB中Document对象里有LocalDateTime类时,如果调用toJson()方法输出JSON格式字符串,这时会抛异常:

org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class java.time.LocalDateTime.
	at org.bson.internal.CodecCache.getOrThrow(CodecCache.java:57)
	at org.bson.internal.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:64)
	at org.bson.internal.ChildCodecRegistry.get(ChildCodecRegistry.java:52)
  ...

是因为Document里没有实现LocalDateTime的编解码器,这是可以把Document先转换成BsonDocument再调用BsonDocument的toJson方法就可以了.

为了方便使用,我创建了一个工具类,实现了Bson,Document,BsonDocument的相互转换:

package org.wjw.mongo.crud.model;

import org.bson.BsonDocument;
import org.bson.Document;
import org.bson.codecs.Codec;
import org.bson.codecs.DecoderContext;
import org.bson.codecs.configuration.CodecProvider;
import org.bson.codecs.configuration.CodecRegistries;
import org.bson.codecs.configuration.CodecRegistry;
import org.bson.codecs.pojo.PojoCodecProvider;
import org.bson.conversions.Bson;

import com.mongodb.MongoClientSettings;

public class DocumentTools {
  private final static CodecProvider   codecProvider  = PojoCodecProvider.builder().automatic(true).build();
  private final static CodecRegistry   codecRegistry  = CodecRegistries.fromRegistries(MongoClientSettings.getDefaultCodecRegistry(), CodecRegistries.fromProviders(codecProvider));
  private final static Codec<Document> codec          = codecRegistry.get(Document.class);
  private final static DecoderContext  decoderContext = DecoderContext.builder().build();

  public static Document bsonDocument2Document(BsonDocument bsonDocument) {
    return codec.decode(bsonDocument.asBsonReader(), decoderContext);
  }

  public static BsonDocument document2BsonDocument(Document document) {
    return document.toBsonDocument(BsonDocument.class, codecRegistry);
  }

  public static BsonDocument bson2BsonDocument(Bson bson) {
    return bson.toBsonDocument(BsonDocument.class, codecRegistry);
  }
}

例如下面代码使用日期范围来查找符合的文档:

  @Test
  void testFindUseDocument() {
    LocalDateTime dateTime = LocalDateTime.of(2022, 6, 10, 17, 0, 0);
    Event         event    = collection.find(com.mongodb.client.model.Filters.eq("dateTime", dateTime)).first();
    System.out.println(event);

    LocalDateTime from     = LocalDateTime.of(2022, 06, 04, 12, 0, 0);
    LocalDateTime to       = LocalDateTime.of(2022, 06, 10, 17, 0, 0);
    Document      document = new Document();
    document.append("dateTime", new Document().append("$gte", from).append("$lte", to));

    BsonDocument    bsonDocument    = DocumentTools.document2BsonDocument(document);  // <1>
    System.out.println(bsonDocument.toJson());

    collection.find(document).forEach(it -> {
      System.out.println(it);
    });
  }

先使用DocumentTools.document2BsonDocument 把document转换成BsonDocument,再调用bsonDocument.toJson() 方法就会输出JSON格式的字符串了

bsonDocument.toJson()输出如下:

{"dateTime": {"$gte": {"$date": "2022-06-04T12:00:00Z"}, "$lte": {"$date": "2022-06-10T17:00:00Z"}}}

<<<<<<<<<<<< [完] >>>>>>>>>>>>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱游泳的老白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值