zoukankan      html  css  js  c++  java
  • jackson使用localdatetime转换json出现问题

    问题】                                  

    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();
            }
    复制代码

     转自https://www.cnblogs.com/yzeng/p/11522411.html

  • 相关阅读:
    基于springBoot使用templates技术
    springBoot将配置文件读取进对象
    Django学习笔记二十二——Django的简易项目之账户注册的实现
    Django学习笔记二十一——Django的auth模块
    Django学习笔记二十——Django请求流程梳理总结
    Django学习笔记一十八——Django中间件的使用
    Django学习笔记一十五——cookies和session
    Django学习笔记一十九——补充内容:视图中的CBV和FBV (2020-05-15 15:05)
    Django学习笔记一十八——Django的数据库可视化操作
    Django学习笔记一十七——Django的FORM表单
  • 原文地址:https://www.cnblogs.com/jasenin/p/12607738.html
Copyright © 2011-2022 走看看