使用 Jackson 库对日期时间的动态序列化反序列化操作

0.背景

因某项目中的数据报表功能在创建年报 和月报时需要生成不同的日期格式,但数据结构未变,为避免类的冗余定义,故使用如下方式来动态设置日期格式,在不同报表是使用不同格式的时间格式来保存数据。

1.代码介绍

PS:此介绍有ChatGPT生成,仅供参考
这段代码演示了如何使用 Jackson 库处理自定义的时间戳序列化和反序列化。它包含以下关键要素:

  1. CustomDateSerializer 类是一个自定义的时间戳序列化器,继承自 JsonSerializer<Date>。它将 Date 对象格式化为指定的日期字符串格式。

  2. CustomDateDeserializer 类是一个自定义的时间戳反序列化器,继承自 StdDeserializer<Date>。它将日期字符串解析为 Date 对象。

  3. Main 类是包含 main 方法的入口类。它创建了一个 ObjectMapper 实例,并通过自定义模块注册自定义序列化器和反序列化器。

  4. createObjectMapperWithCustomModule 方法创建了一个配置了自定义模块的 ObjectMapper 实例。它创建一个简单模块 SimpleModule,并将自定义的序列化器和反序列化器注册到该模块中。

  5. MyClass 类是一个示例类,包含一个使用 @JsonFormat 注解指定格式的时间戳字段 timestamp

main 方法中,首先通过 createObjectMapperWithCustomModule 方法创建了配置了自定义模块的 ObjectMapper 实例。然后,创建了一个 MyClass 对象,并将其序列化为 JSON 字符串。接着,将 JSON 字符串反序列化为 MyClass 对象,并打印出反序列化后的时间戳值。

通过使用自定义的时间戳序列化器和反序列化器,我们可以以指定的日期字符串格式对时间戳进行序列化和反序列化,以满足特定的需求。这种方式允许我们在处理时间戳时更灵活地控制格式化和解析的行为。

2.详细代码

2.1 自定义序列化类

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class CustomDateSerializer extends JsonSerializer<Date> {
    private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Override
    public void serialize(Date value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        String formattedDate = dateFormat.format(value);
        gen.writeString(formattedDate);
    }
}

2.2 自定义反序列化类

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.text.SimpleDateFormat;
import java.util.Date;

public class CustomDateDeserializer extends StdDeserializer<Date> {
    private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public CustomDateDeserializer() {
        super(Date.class);
    }

    @Override
    public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        String dateString = p.getText();
        try {
            return dateFormat.parse(dateString);
        } catch (Exception e) {
            throw new IOException("Failed to parse date: " + dateString, e);
        }
    }
}

2.3 主类

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import java.util.Date;

public class Main {
    public static void main(String[] args) throws Exception {
        MyClass obj = new MyClass();
        obj.setTimestamp(new Date());

        //使用JsonFormat配置的序列化
        ObjectMapper objectMapper = new ObjectMapper();
        String defaultJson = objectMapper.writeValueAsString(obj);
        System.out.println(defaultJson);

        // 自定义序列化操作
        ObjectMapper mapperWithCustomModule = createObjectMapperWithCustomModule();
        String json = mapperWithCustomModule.writeValueAsString(obj);
        System.out.println(json);

        // 自定义反序列化操作
        MyClass obj2 = mapperWithCustomModule.readValue(json, MyClass.class);
        System.out.println(obj2.getTimestamp());
    }

    private static ObjectMapper createObjectMapperWithCustomModule() {
        ObjectMapper objectMapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();
        module.addSerializer(Date.class, new CustomDateSerializer());
        module.addDeserializer(Date.class, new CustomDateDeserializer());
        objectMapper.registerModule(module);
        return objectMapper;
    }

    static class MyClass {
        @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
        private Date timestamp;

        public Date getTimestamp() {
            return timestamp;
        }

        public void setTimestamp(Date timestamp) {
            this.timestamp = timestamp;
        }
    }
}

3.运行结果

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值