zoukankan      html  css  js  c++  java
  • Jackson之LocalDateTime转换,无需改实体类

    【问题】                                  

    Demo:

      LocalDateTime dt = LocalDateTime.now();
            ObjectMapper mapper = new ObjectMapper();
            try {
                String json = mapper.writeValueAsString(dt);
                System.out.println(json);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }

    Jackson默认序列化会将LocalDateTime序列化成:

    {"dayOfMonth":15,"dayOfWeek":"SUNDAY","dayOfYear":258,"hour":14,"minute":6,"month":"SEPTEMBER","monthValue":9,"nano":359000000,"second":55,"year":2019,"chronology":{"id":"ISO","calendarType":"iso8601"}}

    并且该字符串反序列化成LocalDateTime会报错:

    Cannot construct instance of `java.time.LocalDateTime`

    Demo:

        String json = "{"dayOfMonth":15,"dayOfWeek":"SUNDAY","dayOfYear":258,"hour":14,"minute":2,"month":"SEPTEMBER","monthValue":9,"nano":71000000,"second":46,"year":2019,"chronology":{"id":"ISO","calendarType":"iso8601"}}";
            ObjectMapper mapper = new ObjectMapper();
            try {
                LocalDateTime dt = mapper.readValue(json, LocalDateTime.class);
                System.out.println(dt);
            } catch (IOException e) {
                e.printStackTrace();
            }

     就算加了:

    mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    mapper.registerModule(new JavaTimeModule());

    也会报如下错误:

    com.fasterxml.jackson.databind.exc.MismatchedInputException: Expected array or string.

    Demo:

     String json = "{"dayOfMonth":15,"dayOfWeek":"SUNDAY","dayOfYear":258,"hour":14,"minute":2,"month":"SEPTEMBER","monthValue":9,"nano":71000000,"second":46,"year":2019,"chronology":{"id":"ISO","calendarType":"iso8601"}}";
            ObjectMapper mapper = new ObjectMapper();
            try {
                mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
                mapper.registerModule(new JavaTimeModule());
                LocalDateTime dt = mapper.readValue(json, LocalDateTime.class);
                System.out.println(dt);
            } catch (IOException e) {
                e.printStackTrace();
            }

    【解决方案】                                                              

    思路:

      改变jackson内部序列化和反序列化LocalDateTime的方式,序列化时转换为时间戳,反序列化时将时间戳转换为LocalDateTime即可。

    代码:

    创建两个类,分别继承JsonSerializer和JsonDeserializer

    //时间序列化时变为时间戳
    public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
        @Override
        public void serialize(LocalDateTime localDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
            jsonGenerator.writeNumber(localDateTime.toInstant(ZoneOffset.ofHours(8)).toEpochMilli());
        }
    }
    //时间戳反序列化时间
    public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
        @Override
        public LocalDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
            Long timestamp = jsonParser.getLongValue();
            return LocalDateTime.ofEpochSecond(timestamp / 1000, 0, ZoneOffset.ofHours(8));
        }
    }

    使用方法(序列化添加如下3行红色代码)

          LocalDateTime dt = LocalDateTime.now();
            ObjectMapper mapper = new ObjectMapper();
            try {
                JavaTimeModule timeModule = new JavaTimeModule();
                timeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer());
                mapper.registerModule(timeModule);
                String json = mapper.writeValueAsString(dt);
                System.out.println(json);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }

    * 经过此方式序列化得到的结果为:"1568528927273"

    使用方法(反序列化添加如下3行红色代码)

    String json = "1568528927273";
            ObjectMapper mapper = new ObjectMapper();
            try {
                JavaTimeModule timeModule = new JavaTimeModule();
                timeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer());
                mapper.registerModule(timeModule);
                LocalDateTime dt = mapper.readValue(json, LocalDateTime.class);
                System.out.println(dt);
            } catch (IOException e) {
                e.printStackTrace();
            }

    以上就是本文所有内容~~~ 欢迎交流,,分享~~~

  • 相关阅读:
    求助:可以使用任何编程工具做成一个控件或组件,使得在VB中能调用并得到摄像头的参数及图片。
    作为软件工程师,你必须知道的20个常识
    继续C#开发or转做产品
    65行 JavaScript 代码实现 Flappy Bird 游戏
    自上而下的软件开发和自下而上的软件开发
    没有发布过产品的程序员不知道什么是真正的软件
    20个数据库设计的最佳实践
    59条搞笑但却真实无比的编程语录
    自己动手跟着Jwt标准实现Jwt
    Gitlab-Runner基础教程
  • 原文地址:https://www.cnblogs.com/yzeng/p/11522411.html
Copyright © 2011-2022 走看看