当前位置: 首页 > 知识库问答 >
问题:

使用Jackson将Java8 LocalDateTime序列化为UTC时间戳

袁泓
2023-03-14

我刚刚根据新的(ish)Java8时间包将许多日期转换为LocalDateTime。到目前为止,我一直很喜欢这种转换,直到我开始尝试序列化和反序列化。

如何配置Jackson以支持他们?:

LocalDateTime --serialize--

这里有大量关于转换为格式化字符串的资料,但我似乎找不到utc时间戳的现成解决方案。

共有3个答案

史烈
2023-03-14

您可以利用< code>JavaTimeModule,而不是手动重写所有内容:

ObjectMapper om = new ObjectMapper();
om.registerModule(new JavaTimeModule());
om.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, true);
符修杰
2023-03-14

以下解决方案解决了将<code>LocalDateTime</code>序列化/反序列化为时间戳的任务,并且至少与spring boot v1.5相关,还包括@xingbin的回答中未考虑的下一点:

  • 如果需要具有与<code>java.util相同的行为。日期必须使用toInstant()。toEpochMilli()而不是toInstant()。getEpochSecond()
  • 检查null要反序列化的值
  • 可选点:为Jackson<code>ObjectMapper</code>指定此序列化/反序列化配置

时间戳序列化程序类:

public class LocalDateTimeSerializer extends StdSerializer<LocalDateTime> {
    private static final ZoneId DEFAULT_ZONE_ID = ZoneId.of("UTC");

    public LocalDateTimeSerializer() {
        super(LocalDateTime.class);

    }

    @Override
    public void serialize(final LocalDateTime value,
                          final JsonGenerator generator,
                          final SerializerProvider provider) throws IOException {
        if (value != null) {
            final long mills = value.atZone(DEFAULT_ZONE_ID).toInstant().toEpochMilli();
            generator.writeNumber(mills);
        } else {
            generator.writeNull();
        }
    }
}

时间戳反序列化程序类:

public class LocalDateTimeDeserializer extends StdDeserializer<LocalDateTime> {
    private static final ZoneId DEFAULT_ZONE_ID = ZoneId.of("UTC");

    public LocalDateTimeDeserializer() {
        super(LocalDateTime.class);
    }

    @Override
    public LocalDateTime deserialize(final JsonParser parser,
                                     final DeserializationContext context) throws IOException {
        final long value = parser.getValueAsLong();
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(value), DEFAULT_ZONE_ID);
    }
}

对象映射器配置:

@Configuration
public class ObjectMapperConfiguration {
    @Bean
    public ObjectMapper objectMapper() {
        final ObjectMapper objectMapper = new ObjectMapper();
        final SimpleModule module = new SimpleModule();
        module.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer());
        module.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer());
        objectMapper.registerModule(module);
        return objectMapper;
    }
}
章彬郁
2023-03-14

您可以为< code>LocalDateTime自定义序列化程序和反序列化程序,例如:

CustomLocalDateTimeSerializer

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneId;

public class CustomLocalDateTimeSerializer extends StdSerializer<LocalDateTime> {

    protected CustomLocalDateTimeSerializer(Class<LocalDateTime> t) {
        super(t);
    }

    protected CustomLocalDateTimeSerializer() {
        this(null);
    }

    @Override
    public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider sp)
            throws IOException {
        Long epoch = value.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond();
        gen.writeString(epoch.toString());
    }
}

CustomLocalDateTimeDeserializer:

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;

import java.io.IOException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;

class CustomLocalDateTimeDesSerializer extends StdDeserializer<LocalDateTime> {

    protected CustomLocalDateTimeDesSerializer() {
        this(null);
    }

    protected CustomLocalDateTimeDesSerializer(Class<LocalDateTime> t) {
        super(t);
    }

    @Override
    public LocalDateTime deserialize(JsonParser jsonparser, DeserializationContext context)
            throws IOException {
        Long timestamp = Long.parseLong(jsonparser.getText());
        return LocalDateTime.ofInstant(Instant.ofEpochSecond(timestamp), ZoneId.systemDefault());
    }
}

并使用它们:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

import java.time.LocalDateTime;

public class RestObject {

    private LocalDateTime timestamp = LocalDateTime.now();

    @JsonSerialize(using = CustomLocalDateTimeSerializer.class)
    @JsonDeserialize(using = CustomLocalDateTimeDesSerializer.class)
    public LocalDateTime getTimestamp() {
        return timestamp;
    }

    public static void main(String[] args) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();
        // {"timestamp":"1549026058"}
        System.out.println(objectMapper.writeValueAsString(new RestObject()));
    }
}
 类似资料:
  • 问题内容: 使用Jackson XmlMapper注释,如何将XML反序列化为pojo? 我试图使用这样的东西: 当我尝试使用XmlMapper的readValue()时,出现以下错误: 问题答案: 您的课程与您的课程不符。结构比您想象的要简单。请参见以下示例: 简单用法: 上面的程序打印(适用于您): 也可以看看: jackson-dataformat-xml。 主页:Jackson XML d

  • 问题内容: 如何将作为地图的属性序列化为地图的值列表?我已经能够使用吸气剂上的注释进行其他简单的转换。但是,我不确定我想做什么。 问题答案: 我们需要类似的东西,在我们的案例中,我们使用了您所评论的自定义项,这很简单: 使用它的代码:

  • 我正在尝试使用Jackson将ISO8601格式的日期反序列化为Java8。我向ObjectMapper注册了JavaTimeModule,并关闭了设置。 但是,如果试图反序列化将不起作用,因为JavaTimeModule似乎只会反序列化使用UTC时区偏移量格式化的日期时间(例如)。然后我尝试使用注释,如下所示: 就像这样: 然而,这两种方法都不起作用,我得到了一个例外: 这意味着timezone

  • 我有一个JSON字符串,它将空列表标记为而不是。因此,例如,如果我有一个没有子对象的对象,我将收到这样的字符串: 我想将其反序列化为父类,将子类正确设置为子类的空列表。 对于上面的JSON字符串,我想要一个将其id设置为13的对象,并将子元素设置为新的ArrayList 我知道如何为整个类使用注释 然后呢 但是,我想解决从字符串正确实例化列表的一般问题: 我能得到这样的东西吗?

  • 我们在elasticsearch索引中有一个日期字段,其中填充了一个长的。 字段映射为: 我使用和进行此配置: 但是当我试图用一个字段解析索引中的实体时,例如: 我收到一个错误: 我认为,可以将一个长的反序列化为一个日期,但我看不出我遗漏了什么。 如果我把它映射到Long,它当然会起作用,如果值存储为String,并且我们在JsonFormat中正确地对其进行造型和格式化,它也会起作用。但是有没有