在PostgreSQL中存储为JSONB的ZoneDateTime的序列化格式

时间:2018-07-30 14:27:47

标签: java postgresql jackson jsonb zoneddatetime

尝试将复杂数据作为JSONB存储在PostgreSQL中。
除java.time.ZonedDateTime类型的属性的格式外,存储工作正常。

1-给定实体 Route

@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
…
class
…

@Column(name = "stops", columnDefinition = "jsonb")
@Type(type = "jsonb")
@Valid
private List<Stop> stops;
…

具有一个@Embeddable对象 Stop ,其中包含属性:

@Column(name = "date_from")
private ZonedDateTime dateFrom;

2-POST REST端点接收到时:

{…
"dateFrom": "2018-07-28T17:47:50.331+02:00",
…}

将整个JSON映射到实体即可!

但是

3-然后将postgreSQL数据库存储为日期:

{…
"loadingDateFrom": {
    "hour": 17,
    "nano": 331000000,
    "year": 2018,
    "zone": {
        "id": "+02:00",
        "rules": {
            "fixedOffset": true,
            "transitions": [],
            "transitionRules": []
        },
        "totalSeconds": 7200
    },
    "month": "JULY",
    "minute": 47,
    "offset": {
        "id": "+02:00",
        "rules": {
            "fixedOffset": true,
            "transitions": [],
            "transitionRules": []
        },
        "totalSeconds": 7200
    },
    "second": 50,
    "dayOfWeek": "SATURDAY",
    "dayOfYear": 209,
    "chronology": {
        "id": "ISO",
        "calendarType": "iso8601"
    },
    "dayOfMonth": 28,
    "monthValue": 7
},  
…}

预期与端点接收的相同(日期字符串):
“ 2018-07-28T17:47:50.331 + 02:00”

(另一个示例:如果存储为postgreSQL时间戳,例如实体 Stop 中的其他属性,则序列化为日期字符串效果很好)

调用GET REST端点会传递复杂的日期结构,这很糟糕,因为前端中的日期处理很复杂。

问题:

如何实现postgreSQL将日期存储为日期字符串而不是复杂的对象?

经过大量调试,我认为这与Jackson序列化程序有关。我看到DefaultSerializer正在获取ZonedDateTime对象。序列化后,将存储复杂的数据结构。

是否有一种配置格式来格式化日期,而不是编写自己的序列化器/反序列化器?
我试过了:
-date属性的 @JsonFormat(…)不同,但是反序列化总是出现“ JSON解析错误”。无论如何,我都不想指定格式。这应该是开箱即用的。

配置:
jhipster / spring-boot项目
-编译“ com.fasterxml.jackson.datatype:jackson-datatype-jsr310”
-编译“ com.fasterxml.jackson.core:jackson-databind”
-春天:杰克逊:serialization.write_dates_as_timestamps:假

2 个答案:

答案 0 :(得分:0)

使用CustomSerializer:

public class ZonedDateTimeSerialzier extends JsonSerializer<ZonedDateTime>{
@Override
public void serialize(ZonedDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
    String parseDate = null;// parse here zoned date time
    gen.writeString(parseDate);
}
}

然后添加此内容:

@Column(name = "date_from")
@JsonSerialize(using = ZonedDateTimeSerialzier.class)
private ZonedDateTime dateFrom;

如果要全局执行此操作,请在配置类中编写此bean:

@Bean
public Jackson2ObjectMapperBuilder configureObjectMapper() {
    Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
    SimpleModule zonedDateTimeSerializer = new SimpleModule();
    zonedDateTimeSerializer.addSerializer(ZonedDateTime.class,new ZonedDateTimeSerialzier());

    builder.modules(zonedDateTimeSerializer);
    return builder;
}

或者如果您想将时间戳记添加到application.properties中,则:

spring.jackson.serialization.write-dates-as-timestamps=true

或application.yml:

spring:
  jackson:
    serialization: 
      write-dates-as-timestamps: true

答案 1 :(得分:0)

INFO:
由于没有其他解决方案,我将@sajib标记为正确答案。
我用过:

@JsonSerialize(using = ZonedDateTimeSerializier.class)
@JsonDeserialize(using = ZonedDateTimeDeserializier.class)

将Date序列化为String并反序列化String转换为Date