栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

使用Spring Boot> = 2.0.1将ZonedDateTime保存到MongoDB时发生CodecConfigurationException

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用Spring Boot> = 2.0.1将ZonedDateTime保存到MongoDB时发生CodecConfigurationException

像Oliver Drotbohm自己在DATAMONGO-2106中所说的那样,Spring Data MongoDB从未支持使用时区保留日期时间类型。

这些是已知的解决方法:

  1. 使用不带时区的日期时间类型,例如java.time.Instant。(通常建议仅在后端使用UTC,但是我不得不扩展采用不同方法的现有代码库。)
  2. 编写一个自定义转换器,并通过扩展AbstractMongoConfiguration对其进行注册。有关运行示例,请参见我的测试库中的分支转换器。
@Component@WritingConverterpublic class ZonedDateTimeTodocumentConverter implements Converter<ZonedDateTime, document> {    static final String DATE_TIME = "dateTime";    static final String ZONE = "zone";    @Override    public document convert(@Nullable ZonedDateTime zonedDateTime) {        if (zonedDateTime == null) return null;        document document = new document();        document.put(DATE_TIME, Date.from(zonedDateTime.toInstant()));        document.put(ZONE, zonedDateTime.getZone().getId());        document.put("offset", zonedDateTime.getOffset().toString());        return document;    }}@Component@ReadingConverterpublic class documentToZonedDateTimeConverter implements Converter<document, ZonedDateTime> {    @Override    public ZonedDateTime convert(@Nullable document document) {        if (document == null) return null;        Date dateTime = document.getDate(DATE_TIME);        String zoneId = document.getString(ZONE);        ZoneId zone = ZoneId.of(zoneId);        return ZonedDateTime.ofInstant(dateTime.toInstant(), zone);    }}@Configurationpublic class MongoConfiguration extends AbstractMongoConfiguration {    @Value("${spring.data.mongodb.database}")    private String database;    @Value("${spring.data.mongodb.host}")    private String host;    @Value("${spring.data.mongodb.port}")    private int port;    @Override    public MongoClient mongoClient() {        return new MongoClient(host, port);    }    @Override    protected String getDatabaseName() {        return database;    }    @Bean    public CustomConversions customConversions() {        return new MongoCustomConversions(asList(     new ZonedDateTimeTodocumentConverter(),     new documentToZonedDateTimeConverter()        ));    }}
  1. 编写自定义编解码器。至少在理论上。使用Spring Boot 2.0.5时,我的编解码器测试分支无法解组数据,同时与Spring Boot 2.0.1正常工作。
public class ZonedDateTimeCodec implements Codec<ZonedDateTime> {    public static final String DATE_TIME = "dateTime";    public static final String ZONE = "zone";    @Override    public void enpre(final BsonWriter writer, final ZonedDateTime value, final EnprerContext enprerContext) {        writer.writeStartdocument();        writer.writeDateTime(DATE_TIME, value.toInstant().getEpochSecond() * 1_000);        writer.writeString(ZONE, value.getZone().getId());        writer.writeEnddocument();    }    @Override    public ZonedDateTime depre(final BsonReader reader, final DeprerContext deprerContext) {        reader.readStartdocument();        long epochSecond = reader.readDateTime(DATE_TIME);        String zoneId = reader.readString(ZONE);        reader.readEnddocument();        return ZonedDateTime.ofInstant(Instant.ofEpochSecond(epochSecond / 1_000), ZoneId.of(zoneId));    }    @Override    public Class<ZonedDateTime> getEnprerClass() {        return ZonedDateTime.class;    }}@Configurationpublic class MongoConfiguration extends AbstractMongoConfiguration {    @Value("${spring.data.mongodb.database}")    private String database;    @Value("${spring.data.mongodb.host}")    private String host;    @Value("${spring.data.mongodb.port}")    private int port;    @Override    public MongoClient mongoClient() {        return new MongoClient(host + ":" + port, createOptions());    }    private MongoClientOptions createOptions() {        CodecProvider pojoCodecProvider = PojoCodecProvider.builder()     .automatic(true)     .build();        CodecRegistry registry = CodecRegistries.fromRegistries(     createCustomCodecRegistry(),     MongoClient.getDefaultCodecRegistry(),     CodecRegistries.fromProviders(pojoCodecProvider)        );        return MongoClientOptions.builder()     .precRegistry(registry)     .build();    }    private CodecRegistry createCustomCodecRegistry() {        return CodecRegistries.fromCodecs(     new ZonedDateTimeCodec()        );    }    @Override    protected String getDatabaseName() {        return database;    }}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/408523.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号