Spring Data JPA - 用于 json 序列化的 ZonedDateTime 格式

Posted

技术标签:

【中文标题】Spring Data JPA - 用于 json 序列化的 ZonedDateTime 格式【英文标题】:Spring Data JPA - ZonedDateTime format for json serialization 【发布时间】:2015-10-16 03:46:07 【问题描述】:

ZonedDateTime 的 json 序列化有问题。当转换为 json 时,它会产生一个巨大的对象,我不希望每次都传输所有数据。所以我尝试将其格式化为ISO,但它不起作用。我怎样才能让它格式化?

这是我的实体类:

@MappedSuperclass
public abstract class AuditBase 

    @Id
    @GeneratedValue
    private Long id;

    @CreatedDate
    private ZonedDateTime createdDate;

    @LastModifiedDate
    private ZonedDateTime lastModifiedDate;

    @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
    public ZonedDateTime getLastModifiedDate() 
        return lastModifiedDate;
    

    public void setLastModifiedDate(ZonedDateTime lastModifiedDate) 
        this.lastModifiedDate = lastModifiedDate;
    

    @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
    public ZonedDateTime getCreatedDate() 
        return createdDate;
    

    public void setCreatedDate(ZonedDateTime createdDate) 
        this.createdDate = createdDate;
    

    public Long getId() 
        return id;
    

    public void setId(Long id) 
        this.id = id;
    

    @PrePersist
    public void prePersist() 
        this.createdDate = ZonedDateTime.now();
        this.lastModifiedDate = ZonedDateTime.now();
    

    @PreUpdate
    public void preUpdate() 
        this.lastModifiedDate = ZonedDateTime.now();
    

【问题讨论】:

【参考方案1】:

我猜你正在使用 Jackson 进行 json 序列化,Jackson 现在有一个用于 Java 8 新日期时间 API 的模块,https://github.com/FasterXML/jackson-datatype-jsr310。

将此依赖项添加到您的 pom.xml 中

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.6.0</version>
</dependency>

这是它的用法:

 public static void main(String[] args) throws JsonProcessingException 
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.registerModule(new JavaTimeModule());
    System.out.println(objectMapper.writeValueAsString(new Entity()));


static class Entity 
    ZonedDateTime time = ZonedDateTime.now();

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ")
    public ZonedDateTime getTime() 
        return time;
    

输出是:

"time":"2015-07-25T23:09:01.795+0700"

注意:如果您的 Jackson 版本是 2.4.x,请使用

objectMapper.registerModule(new JSR310Module());

希望这会有所帮助!

【讨论】:

我遇到了一件很奇怪的事情:"time":1473923145.038000000。使用您的解决方案,我现在可以根据需要获得 "time":"2016-09-15T07:57:26.602+0000"。 对我来说,registerModule 就足够了。我不必触摸实体。谢谢!! 当有人从 pom 文件中发布 5 行 XML 时,我总是感到不寒而栗,Gralde 获胜 ;) @KlausGroenbaek:很公平,Gradle 看起来更简洁,但有时我们只需要让它工作。 @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone = "UTC") => 2019-10 -16T08:23:51.817Z【参考方案2】:

以上答案有效,但如果您不想触及现有实体类,以下设置将适用于ZonedDateTime

  public static ObjectMapper getMapper() 
    ObjectMapper mapper = new ObjectMapper(); 
    mapper.registerModule(new JavaTimeModule());    
    return mapper.configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS, false)
.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS,false)
                        .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false)
                        .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
                        .setVisibility(mapper.getSerializationConfig()
                                .getDefaultVisibilityChecker()
                                .withFieldVisibility(JsonAutoDetect.Visibility.ANY)
                                .withGetterVisibility(JsonAutoDetect.Visibility.NONE)
                                .withSetterVisibility(JsonAutoDetect.Visibility.NONE)
                                .withCreatorVisibility(JsonAutoDetect.Visibility.NONE)); 
    

图书馆:

<dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-csv</artifactId>
            <version>$jackson.dataformat.csv.version</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
        </dependency>

【讨论】:

【参考方案3】:

我解决了将以下属性设置为application.yml 的问题。

    spring:
      jackson:
        serialization:
          write_dates_as_timestamps: false

我使用spring-boot:2.3.8.RELEASEdependency-management:1.0.10.RELEASE

更多详情see this link.

【讨论】:

以上是关于Spring Data JPA - 用于 json 序列化的 ZonedDateTime 格式的主要内容,如果未能解决你的问题,请参考以下文章

使用 Jackson Annotation 将 json 数据映射到 Spring Data JPA 中的预期值

使用Spring-Data-JPA进行Spring启动:每次请求时都会填充ArrayList / JSON对象

Spring data jpa JavassistLazyInitializer 不仅是Json序列化问题.以及解决办法

Spring Boot 2. Jackson json 序列化或 Spring Data JPA FetchType.Lazy

Spring data jpa 不适用于自动配置的 entityManagerFactory

jsonb字段上的Spring-Data-JPA本机查询